nullptr与constexpr
一、nullptr
-
nullptr
的出现是为了替代NULL
-
C++98
中,NULL
和0是不做区分的,导致以下程序void foo(char *a) { cout<<"String"; } void foo(int a) { cout<<"Number"; } int main() { char *ch = NULL; foo(NULL); return 0; }
会报警告,因为其导致
C++
重载特性发生了混乱 -
C++11/14
中引入了nullptr
关键字,专门用来区分空指针、0。nullptr
的类型为nullptr_t
,能够隐式的转换为任何指针或成员指针的类型,也能和他们进行相等或者不等的比较。 编译运行如下程序:void foo(char *); void foo(int); int main() { if(NULL == (void *)0) std::cout << "NULL == 0" << std::endl; else std::cout << "NULL != 0" << std::endl; foo(0); // foo(NULL); // 编译无法通过 foo(nullptr); return 0; } void foo(char *ch) { std::cout << "call foo(char*)" << std::endl; } void foo(int i) { std::cout << "call foo(int)" << std::endl; }
运行结果:
NULL == 0 call foo(int) call foo(char*)
-
因此当需要使用
NULL
时候,直接使用nullptr
二、constexpr
-
一般来说,常量表达式中使用的变量必须被声明为
const
,就像:int len_foo() { return 5; } int main() { int len = 5; char arr_1[len+5]; // 非法 const int len_2 = 10; char arr_2[len_2+5]; // 合法 char arr_3[len_foo()+5]; // 非法 return 0; }
虽然编译可以通过,但不建议使用非法的形式
-
constexpr
可以让用户显式的声明函数或对象构造函数在编译器会成为常数,这个关键字明确的告诉编译器应该去验证len_foo
在编译器就应该是一个常数 ,即constexpr int len_foo() { return 5; }
-
从
C++14
开始,constexptr
函数可以在内部使用局部变量、循环和分支等简单语句:constexpr int fibonacci(const int n) { if(n == 1) return 1; if(n == 2) return 1; return fibonacci(n-1)+fibonacci(n-2); }