`constexpr`和`const`之间的区别?
基本含义和语法
这两个关键字都可以在对象声明和函数中使用。应用于对象的基本区别是:
const声明一个对象为常量。这意味着一个保证,一旦初始化,该对象的值不会改变,编译器可以利用这个事实进行优化。它还有助于防止程序员编写修改初始化后不打算修改的对象的代码。constexpr声明一个对象适合在Standard调用常量表达式中使用。但请注意,这constexpr不是唯一的方法。
应用于功能的基本区别是:
const只能用于非静态成员函数,而不能用于一般函数。它保证了成员函数不会修改任何非静态数据成员。constexpr可以与成员和非成员函数以及构造函数一起使用。它声明了适用于常量表达式的函数。如果函数符合某些标准(7.1.5 / 3,4),编译器将只接受它,最重要的是(†):- 函数体必须是非虚拟的,非常简单:除typedef和静态断言之外,只
return允许一个语句。在构造函数的情况下,只允许初始化列表typedefs和静态声明。(= default和= delete也被允许使用,但。) - 参数和返回类型必须是文字类型(即一般来说,非常简单的类型,通常是标量或集合)
- 函数体必须是非虚拟的,非常简单:除typedef和静态断言之外,只
常量表达式
如上所述,constexpr声明两个对象以及适合在常量表达式中使用的函数。一个恒定的表达不仅仅是不变的:
- 它可用于需要编译时评估的地方,例如模板参数和数组大小说明符:
templateclass fixed_size_list { /*...*/ }; fixed_size_listmylist; // X must be an integer constant expression int numbers[X]; // X must be an integer constant expression - 但请注意:
- 声明一些东西
constexpr并不一定保证在编译时会被评估。它可以用于此类,但也可以在运行时评估的其他地方使用。 - 一个对象可能适合在常量表达式中使用,而不需要声明
constexpr。例:int main() { const int N = 3; int numbers[N] = {1, 2, 3}; // N is constant expression return 0; }
这是可能的,因为
N在声明时使用常量来保持常量和初始化,即使没有声明,它也满足常量表达式的条件constexpr。 - 声明一些东西
那么我什么时候需要使用constexpr?
- 像上面这样的对象
N可以作为常量表达式使用而不需要声明constexpr。所有对象都是如此:const- 积分或枚举类型和
- 在声明时用一个本身就是常量表达式的表达式进行初始化
[这是由于§5.19/ 2:一个常量表达式不能包括一个子表达式,涉及“左值,右值修改,除非[...]整数或枚举类型的glvalue”感谢理查史密斯纠正我早些时候声称这对所有字面类型都是正确的。]
- 要使函数适合在常量表达式中使用,必须明确声明
constexpr; 仅仅满足常量表达函数的标准是不够的。例:templateclass list { }; constexpr int sqr1(int arg) { return arg * arg; }int sqr2(int arg) { return arg * arg; }int main() { const int X = 2; listmylist1; // OK: sqr1 is constexpr list mylist2; // wrong: sqr2 is not constexpr return 0; }
我什么时候可以同时使用const和constexpr 一起使用?
A.在对象声明中。当两个关键字都指向同一个被声明的对象时,这是不必要的。constexpr意味着const。
constexpr const int N = 5;
是相同的
constexpr int N = 5;
但是,请注意,可能会出现以下情况:关键字分别指向声明的不同部分:
static constexpr int N = 3;int main()
{constexpr const int *NP = &N;return 0;
}
在这里,NP被声明为一个地址常量表达式,即一个本身就是一个常量表达式的指针。(当通过将地址运算符静态/全局常量表达式生成的地址。这是可能的。)在这里,无论是constexpr和const是必需的:constexpr总是指表达被宣布(在这里NP),而const指的是int(它声明了一个指针-给const)。删除const会导致表达式不合法(因为(a)非const对象的指针不能是常量表达式,(b)&N实际上是指向常量的指针)。
B.在成员函数声明中。在C ++ 11中,也constexpr暗示const了成员函数。但是,这在C ++ 14中可能会改变。根据目前的草案,由于建议修改§7.1.5/ 8 ,constexpr将const 仅针对对象,而不针对成员职能。因此,在C ++ 11下声明一个成员函数为
constexpr void f();
将不得不被宣布为
constexpr void f() const;
在C ++ 14下仍然可以用作const函数。最好将你的constexpr成员函数标记为const现在,以免稍后改变很多代码。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
