素胚勾勒不出你
基本意义和句法这两个关键字都可以用于对象和函数的声明。应用于对象这是:const声明对象为常量..这意味着,一旦初始化,该对象的值就不会改变,编译器可以利用这一事实进行优化。它还有助于防止程序员编写修改初始化后不打算修改的对象的代码。constexpr声明一个适合在标准调用的对象中使用的对象常数表达式..但请注意constexpr不是唯一的办法。适用于功能基本的区别是:const只能用于非静态成员函数,一般不能用于函数.它保证成员函数不会修改任何非静态数据成员。constexpr既可用于成员函数,也可用于非成员函数,也可用于构造函数。它声明该函数适合用于常数表达式..只有当函数满足某些条件(7.1.5/3,4)时,编译器才会接受它,最重要的是(†):函数体必须是非虚拟的,并且非常简单:除了类型防御和静态断言之外,只有一个return允许陈述。在构造函数的情况下,只允许初始化列表、类型防御和静态断言。(= default和= delete但也是允许的。)从C+14开始,规则就更宽松了,从那时起,在一个函数中允许这样做:asm声明,agoto语句,具有其他标签的语句。case和default、尝试块、非文字类型变量的定义、静态或线程存储持续时间变量的定义、未对其执行初始化的变量的定义。参数和返回类型必须为文字类型(一般来说,非常简单的类型,通常是标量或集合)常数表达式如前所述,constexpr声明两个对象以及适合在常量表达式中使用的函数。常量表达式不仅仅是常量:它可以用于需要编译时评估的地方,例如模板参数和数组大小说明符:template<int N>class fixed_size_list{ /*...*/ };fixed_size_list<X> mylist;
// X must be an integer constant expressionint numbers[X];
// X must be an integer constant expression但请注意:这是可能的,因为N,它是常量,并且在声明时使用文字初始化,它满足常量表达式的条件,即使它没有声明。constexpr.宣布某事为constexpr并不一定能保证在编译时对其进行评估。它可以使用对于这种情况,也可以在运行时对其进行评估的其他地方使用。对象可以,可能适合在常量表达式中使用无被宣布constexpr..例子:int main(){
const int N = 3;
int numbers[N] = {1, 2, 3}; // N is constant expression}所以我什么时候才能用constexpr?阿对象喜欢N以上可用作常量表达式。无被宣布constexpr..以下所有对象都是如此:[这是由于第5.19/2节:常数表达式不得包括涉及“lvalue-rvalue修改”的子表达式,除非[…]是整数类型或枚举类型的极值[…]。感谢理查德·史密斯纠正了我先前关于所有文字类型都是如此的说法。]const整数型或计数型和在声明时使用本身是常量表达式的表达式初始化为了功能为了适合在常量表达式中使用,它必明确声明constexpr它仅仅满足常数表达式函数的准则是不够的.例子:template<int N>class list{ };constexpr int sqr1(int arg){ return arg * arg; }int sqr2(int arg)
{ return arg * arg; }int main(){
const int X = 2;
list<sqr1(X)> mylist1; // OK: sqr1 is constexpr
list<sqr2(X)> mylist2; // wrong: sqr2 is not constexpr}我什么时候可以/应该同时使用,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;}这里,NP声明为地址常量表达式,即本身为常量表达式的指针。(当通过将地址运算符应用于静态/全局常量表达式生成地址时,这是可能的。)在这里,都是constexpr和const需要:constexpr总是引用被声明的表达式(在这里)NP),同时const指int(它声明了一个指向Const的指针)。移除const将表达式呈现为非法(因为(A)指向非Const对象的指针不能是常量表达式,并且(B)&N实际上是一个指向常量的指针)。B.成员职能声明。在C+11中,constexpr暗示const,而在C+14和C+17中,情况并非如此。在C+11下声明为constexpr void f();需要宣布为constexpr void f() const;在C+14下,以便仍然可用作const功能。