查找指向 NULL 的指针
Finding a Pointer to NULL
我有 int* foo[SIZE]
,我想在其中搜索指向 NULL
的第一个元素。
但是当我这样做时:
std::find(foo, foo + SIZE, NULL)
我收到错误:
error C2446: '==' : no conversion from 'const int' to 'int *'
我应该只使用 static_cast<int*>(NULL)
而不是 NULL
吗?
C++11 通过 nullptr
解决了这个问题,但在 C++03
中这不是我的选择
tl;dr:使用 nullptr
,或定义您自己的等价物。
问题是 NULL
是一些扩展为值为零的整型常量表达式的宏。为了调用该函数,std::find
必须推导类型并使用值 (0
)。
您不能将 int*
与 int
进行比较,因此会出现错误。就函数而言,您只是向它传递了一些恰好为零的常规旧 int
,并且这些不能转换为空指针;它们必须是整数常量表达式。
通常 NULL
"works" 因为它在不被视为整数形式的上下文中使用,例如:
if (ptr == NULL)
因为这里保持"integral constant expression"状态,所以转换为比较类型的空指针。
如果您使用的是 C++11 或更高版本,则应使用 nullptr
,因为这实际上是一个空指针,而不是转换为它的整数。您所描述的实际上是引入 nullptr
.
的激励因素之一
如果您需要,nullptr
有多种 C++03 实现。我在这个答案的底部附加了 classic 实现。
此外,如果可能,您应该更喜欢 std::array
(如果需要,Boost 有一个),或者至少使用 std::begin
和 std::end
来获取数组开始和结束指针(同样,有这个浮动的实现):
#include <algorithm>
#include <array>
int main() {
std::array<int*, 8> foo = {};
std::find(foo.begin(), foo.end(), nullptr);
}
总而言之,在紧要关头强制转换为您的类型的空指针是一个有效的解决方案。 nullptr
实际上只是 "a thing that converts to the null pointer of the needed type".
的缩写
这是一个 nullptr
实现,最初由 Scott Meyers 创建:
const
struct nullptr_t {
template <typename T>
operator T*() const {
return 0;
}
template <typename C, typename T>
operator T C::*() const {
return 0;
}
private:
void operator&() const;
} nullptr = {};
语法看起来有点滑稽,因为我们通常不会同时定义 class 和变量。显然,如果你想保持 C++11 兼容,nullptr
不是可用的标识符。 null_ptr
或 nullpointer
是不错的选择。
这个问题实际上在 Herb Sutter 和 Bjarne Stroustrup 中被指出:A name for the null pointer: nullptr
:
Distinguishing between null and zero. The null pointer and an integer 0 cannot be distinguished well for overload resolution. For example, given two overloaded functions f(int)
and f(char*)
, the call f(0)
unambiguously resolves to f(int)
. There is no way to write a call to f(char*)
with a null pointer value without writing an explicit cast (i.e., f((char*)0)
) or using a named variable
所以我们看到这个问题可以通过以下任一方式解决:
- 显式转换
- 类型匹配的值的声明,例如:
const int* piNULL = NULL
理想情况下,当使用显式强制转换时,可以避免 C 风格强制转换。这些 C++ 样式中的任何一个都有效地转换 returns 包含地址 NULL
:
的 int*
reinterpret_cast<int*>(NULL)
static_cast<int*>(NULL)
http://en.cppreference.com/w/cpp/types/NULL 断言:
A null pointer constant may be implicitly converted to any pointer type; such conversion results in the null pointer value of that type
并且由于 static_cast
:
Converts between types using a combination of implicit and user-defined conversions
static_cast
比 reinterpret_cast
更准确地定义了预期的转换类型:
Converts between types by reinterpreting the underlying bit pattern
因此,在 C++03 中 static_cast<int*>(NULL)
是 C++11 的 nullptr
中可以实现的最严格的内联定义.
我有 int* foo[SIZE]
,我想在其中搜索指向 NULL
的第一个元素。
但是当我这样做时:
std::find(foo, foo + SIZE, NULL)
我收到错误:
error C2446: '==' : no conversion from 'const int' to 'int *'
我应该只使用 static_cast<int*>(NULL)
而不是 NULL
吗?
C++11 通过 nullptr
解决了这个问题,但在 C++03
tl;dr:使用 nullptr
,或定义您自己的等价物。
问题是 NULL
是一些扩展为值为零的整型常量表达式的宏。为了调用该函数,std::find
必须推导类型并使用值 (0
)。
您不能将 int*
与 int
进行比较,因此会出现错误。就函数而言,您只是向它传递了一些恰好为零的常规旧 int
,并且这些不能转换为空指针;它们必须是整数常量表达式。
通常 NULL
"works" 因为它在不被视为整数形式的上下文中使用,例如:
if (ptr == NULL)
因为这里保持"integral constant expression"状态,所以转换为比较类型的空指针。
如果您使用的是 C++11 或更高版本,则应使用 nullptr
,因为这实际上是一个空指针,而不是转换为它的整数。您所描述的实际上是引入 nullptr
.
如果您需要,nullptr
有多种 C++03 实现。我在这个答案的底部附加了 classic 实现。
此外,如果可能,您应该更喜欢 std::array
(如果需要,Boost 有一个),或者至少使用 std::begin
和 std::end
来获取数组开始和结束指针(同样,有这个浮动的实现):
#include <algorithm>
#include <array>
int main() {
std::array<int*, 8> foo = {};
std::find(foo.begin(), foo.end(), nullptr);
}
总而言之,在紧要关头强制转换为您的类型的空指针是一个有效的解决方案。 nullptr
实际上只是 "a thing that converts to the null pointer of the needed type".
这是一个 nullptr
实现,最初由 Scott Meyers 创建:
const
struct nullptr_t {
template <typename T>
operator T*() const {
return 0;
}
template <typename C, typename T>
operator T C::*() const {
return 0;
}
private:
void operator&() const;
} nullptr = {};
语法看起来有点滑稽,因为我们通常不会同时定义 class 和变量。显然,如果你想保持 C++11 兼容,nullptr
不是可用的标识符。 null_ptr
或 nullpointer
是不错的选择。
这个问题实际上在 Herb Sutter 和 Bjarne Stroustrup 中被指出:A name for the null pointer: nullptr
:
Distinguishing between null and zero. The null pointer and an integer 0 cannot be distinguished well for overload resolution. For example, given two overloaded functions
f(int)
andf(char*)
, the callf(0)
unambiguously resolves tof(int)
. There is no way to write a call tof(char*)
with a null pointer value without writing an explicit cast (i.e.,f((char*)0)
) or using a named variable
所以我们看到这个问题可以通过以下任一方式解决:
- 显式转换
- 类型匹配的值的声明,例如:
const int* piNULL = NULL
理想情况下,当使用显式强制转换时,可以避免 C 风格强制转换。这些 C++ 样式中的任何一个都有效地转换 returns 包含地址 NULL
:
int*
reinterpret_cast<int*>(NULL)
static_cast<int*>(NULL)
http://en.cppreference.com/w/cpp/types/NULL 断言:
A null pointer constant may be implicitly converted to any pointer type; such conversion results in the null pointer value of that type
并且由于 static_cast
:
Converts between types using a combination of implicit and user-defined conversions
static_cast
比 reinterpret_cast
更准确地定义了预期的转换类型:
Converts between types by reinterpreting the underlying bit pattern
因此,在 C++03 中 static_cast<int*>(NULL)
是 C++11 的 nullptr
中可以实现的最严格的内联定义.