我看到这nullptr
是在 Visual Studio 2010 中实现的。我喜欢这个概念并希望尽快开始使用它;但是 GCC 还不支持它。我的代码需要在两者上运行(但不必与其他编译器一起编译)。
有没有办法“模仿”它?就像是:
#define nullptr NULL
(这显然根本不起作用,这只是为了表明我的意思。)
官方提案有一个解决方法 -
const // this is a const object...
class {
public:
template<class T> // convertible to any type
operator T*() const // of null non-member
{ return 0; } // pointer...
template<class C, class T> // or any type of null
operator T C::*() const // member pointer...
{ return 0; }
private:
void operator&() const; // whose address can't be taken
} nullptr = {}; // and whose name is nullptr
看起来 gcc 从4.6开始支持 nullptr 。
此外,gcc(实际上是 g++)多年来一直有扩展 __null 。这在 nullptr 提案出来时算作行业实施经验。
__null 扩展可以检测特殊情况并发出警告,例如意外地将 NULL 传递给布尔参数,而它本来是要传递给指针参数的(对函数所做的更改,忘记调整调用端)。
当然,这不是便携式的。上面的模板解决方案是可移植的。
它看起来像 gcc 4.6.1 (Ubuntu 11.11 oneiric),添加了 nullptr。
对我的 hpp/cpp 文件进行快速、递归的 sed 查找和替换对我来说效果很好:
find . -name "*.[hc]pp" | xargs sed -i 's/NULL/nullptr/g'
您很可能忘记了 -std=c++0x 。我的Mingw版本的gcc是4.6.1/4.7.1,都支持nullptr。
根据《The c++ standard library, a tutorial and reference, 2nd》中的描述,nullptr 是一个关键字,可以自动转换为每个指针类型但不能转换为整数类型,这样就克服了 NULL 的缺点,它对后面的重载函数有歧义: 无效 f(int); 无效f(无效*);
f(NULL); // 模棱两可的 f(nullptr); // 好的
在VC2010中测试这个特性显示MSDN文档与实际编译器有冲突,文档中说:
nullptr 关键字不是类型,不支持用于:
大小
类型标识
抛出空指针
实际上在VC2010中,以上所有的操作符/表达式都是合法的。sizeof(nullptr) 结果 4. typeid.name() 结果 std::nullptr_t 和 throw nullptr 可以被“const void *”和“void *”(以及其他指针类型)捕获。
虽然 gcc(4.7.1) 对 nullptr 看起来更严格,但 throw nullptr 不能被“void *”捕获,可以被“...”捕获