查找指针为NULL

Jon*_*Mee 1 c++ null casting nullptr c++03

我有int* foo[SIZE],我想搜索它指向的第一个元素NULL.

但是当我这样做时:

 std::find(foo, foo + SIZE, NULL)
Run Code Online (Sandbox Code Playgroud)

我收到错误:

错误C2446:'==':没有从'const int'转换为'int*'

我应该只使用static_cast<int*>(NULL)而不是NULL

C++ 11解决了这个问题,nullptr但在C++ 03中我不是一个选择

GMa*_*ckG 6

tl; dr:使用nullptr或定义自己的等价物.


问题是,NULL某些宏会扩展为值为零的整数常量表达式.为了调用该函数,std::find必须推导出类型并使用value(0).

你不能比较int*int,因此错误.就函数而言,你只是传递了一些int恰好为零的常规旧函数,并且那些函数无法转换为空指针; 它们必须是整数常量表达式.

通常NULL"有效",因为它在上下文中使用,它不被视为整数形式,例如:

if (ptr == NULL)
Run Code Online (Sandbox Code Playgroud)

因为这里它保持其"整型常量表达式"状态,所以转换为compare-to类型的空指针.

nullptr如果您使用的是C++ 11或更高版本,则应该使用它,因为这实际上是一个空指针,而不是转换为它的整数.你所描述的实际上是引入的激励因素之一nullptr.

nullptr如果需要,可以使用各种C++ 03实现.我在这个答案的底部附上了经典的实现.

另外,std::array如果可能的话,你应该更喜欢(Boost有一个,如果你需要它),或者至少使用std::beginstd::end获得数组的开始和结束指针(同样,有这种浮动的实现):

#include <algorithm>
#include <array>

int main() {
    std::array<int*, 8> foo = {};
    std::find(foo.begin(), foo.end(), nullptr);
}
Run Code Online (Sandbox Code Playgroud)

所有人都说,在压缩到你的类型的空指针是一个有效的解决方案.nullptr实际上只是"转换为所需类型的空指针的事物"的简写.


这是一个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 = {};
Run Code Online (Sandbox Code Playgroud)

语法看起来有点滑稽,因为我们通常不会同时定义类和变量.显然,如果你想保持C++ 11兼容,那么nullptr它不是一个可用的标识符.null_ptr或者nullpointer是很好的选择.