目的是为了代替NULL。传统C++会把NULL、0视为一种东西,这取决于编译器如何定义NULL。有些编译器会定义为((void)* 0),有些会直接定义为0。
C++不允许直接将void 隐式转换到其他类型。如果编译器尝试把NULL定义为((void) 0),如下代码:
char *ch = NULL;
由于C++没有 void * 的隐式转换,只好将NULL定义为0。表面上是解决了当前问题,但是这样做会产生重载混乱的新问题,如下代码:
void foo(char*); void foo(int); ... foo(NULL); //这个函数会调用 foo(int),不符合直觉,很麻烦
C++11引入了nullptr关键字,专门用来区分空指针、0。nullptr的类型为nullptr_t,能够隐式的转换成任何指针或成员指针的类型,也能和它们进行相等或者不相等比较。
所以,作为新时代的C++程序员,请养成使用nullptr的习惯。
constexprC++中数组的长度必须是一个常量表达式,你可以以前通过如下代码也可以定义一个数组:
const int len = 10; int arr[len] = { 0 };
上面的代码可能在大部分编译器上可以跑,但是其实在C++中这是非法的。如果用古老一点的编译器,是会报错的,但是现在的编译器大部分都做了优化,其实这一点非常的不好。
C++11引入了 constexpr关键字,让用户显示的声明函数或对象构造函数在编译期会成为常量表达式。而且,constexpr可以修饰递归,如下代码:
constexpr int fibonacci(const int n) { return n == 1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); //斐波那契数列 } int arr[fibonacci(4)] = { 0 }; //声明了一个有3个int元素的数组,每一个元素都是0
C++11引入的constexpr关键字只能修饰简单的函数,就是函数实现只能由 return 一行代码。从C++14开始,constexpr函数可以在内部使用局部变量、循环和分支等简单语句,如下代码:
constexpr int fibonacci(const int n) { if (n == 1) { return 1; } if (n == 2) { return 1; } return fibonacci(n - 1) + fibonacci(n - 2); }
和上面的那段代码功能一样,逻辑也是一样的,但是在C++11中是跑不了的。
注意事项1.constexpr 修饰符是将编译期运算的结果变成常量表达式,也就是说 constexpr 修饰的对象也要是一个确定不变的值,最起码需要是 const 修饰的值。如下代码:
int a = 1, b = 2; const int c = 1, d = 2; constexpr int value1 = a + b; //错误,a 和 b 是变量,无法在编译期计算出常量值 constexpr int value2 = c + d; //可以,c 和 d 是 const 常量,可以在编译期确定其值 constexpr int value3 = 1 + 2; //更可以了
2.如果是修饰函数,那么返回值一定不能是void ,也就是说一定要有返回值.
3.C++11时期的constexpr有诸多限制,函数体通常只有一句 return 语句,函数体内既不能声明变量,也不能使用for语句之类的常规控制流语句。
4.对于自定义类型(自定义类和自定义结构体),不能直接用constexpr修饰。正确的做法应该是在该类型的内部添加一个常量构造函数。如下代码:
struct myType { constexpr myType(string name, int age):m_name(name), m_age(age) {}; //常量构造函数 string m_name; int m_age; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)