modern c++ 系列关于空指针推荐用 nullptr 而不是 NULL(0, 或者0L)
为什么要用nullptr
考虑下面基于两个场景
- 函数重载
void f(int);
void f(long);
void f(void*);
当你想调用第三个函数 f(NULL) 时
很可惜最终调用的是第一个函数, 甚至可能是第二个函数(视NULL的定义而论)
- 模版函数场景
template<typename Func, typename Ptr>
void my_invoke(Func func, Ptr ptr) {
func(ptr);
}
void fi(int){
cout << "fi(int)" << endl;
}
void fl(long){
cout << "fl(long)" << endl;
}
void fv(void*){
cout << "fv(void*)" << endl;
}
int main() {
my_invoke(fv, NULL); // 不行, 因为推到出的Ptr是int
my_invoke(fv, nullptr) //ok
nullptr 大致实现
#include <numeric>
using namespace std;
template<typename R, typename ...Args>
struct Fu {
using type = R(*)(Args...);
};
struct my_nullptr_t {
constexpr my_nullptr_t() {}
constexpr my_nullptr_t(int __nat::*) {}
constexpr operator int () const {return 0;}
// 转裸指针
template <class _Tp>
constexpr
operator _Tp* () const {return 0;}
// 转函数指针
template <class Tp, class ...Args>
constexpr
operator typename Fu<Tp, Args...>::type() const {return 0;}
// 转成员对象指针
template <class _Tp, class _Up>
constexpr
operator _Tp _Up::* () const {return 0;}
friend constexpr bool operator==(my_nullptr_t, my_nullptr_t) {return true;}
friend constexpr bool operator!=(my_nullptr_t, my_nullptr_t) {return false;}
};
inline constexpr my_nullptr_t get_nullptr_t() {return my_nullptr_t(0);}
#define my_nullptr get_nullptr_t()
class A{
public:
static int z;
};
int add(int a) {
return a + 1;
}
int main() {
int A::* x = my_nullptr;
int(*fz)(int, int) = my_nullptr;
int* zz = my_nullptr;
}