当前位置: 首页 > 知识库问答 >
问题:

'constexpr'与'const'之间的差异

王曜文
2023-03-14
  • 什么时候只能使用其中的一个?
  • 何时可以同时使用和如何选择一个?

共有1个答案

西门骁
2023-03-14

这两个关键字既可以用于对象的声明,也可以用于函数的声明。应用于对象时的基本区别是:

>

  • const将对象声明为常量。这意味着一种保证,即一旦初始化,该对象的值就不会改变,编译器可以利用这一事实进行优化。它还有助于防止程序员编写修改对象的代码,而这些对象在初始化后不打算修改。

    constexpr声明一个对象适合在标准的常量表达式中使用。但请注意,constexpr并不是执行此操作的唯一方法

      null

    如上所述,constexpr声明了适合在常量表达式中使用的对象和函数。常数表达式不仅仅是常数:

    >

  • 它可以用于需要编译时计算的地方,例如,模板参数和数组大小说明符:

      template<int N>
      class fixed_size_list
      { /*...*/ };
    
      fixed_size_list<X> mylist;  // X must be an integer constant expression
    
      int numbers[X];  // X must be an integer constant expression
    

    但请注意:

         int main()
         {
           const int N = 3;
           int numbers[N] = {1, 2, 3};  // N is constant expression
         }
    
      null

    [这是由于§5.19/2:常数表达式不得包含涉及“lvalue-to-rvalue修改的子表达式,除非[…]整数或枚举类型的glvalue[…]”,这要感谢Richard Smith纠正了我先前的说法,即这对所有文字类型都是正确的。]

    >

  • 要使函数适合在常量表达式中使用,它必须显式声明为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
     }
    

    什么时候可以同时使用constconstexpr

    a.在对象声明中。当两个关键字都引用要声明的相同对象时,这永远不是必需的。constexpr表示const

    constexpr const int N = 5;
    

    constexpr int N = 5;
    

    但是,请注意,可能会出现关键字各自引用声明的不同部分的情况:

    static constexpr int N = 3;
    
    int main()
    {
      constexpr const int *NP = &N;
    }
    
    constexpr void f();
    
    constexpr void f() const;
    

  •  类似资料:
    • 在swift中似乎有两个相等运算符:双相等()和三相等(),这两者有什么区别?

    • 对于定义像下面这样的整型类型的编译时常量(在函数和类作用域),哪种语法是最好的? 也适用于C++98/03编译器,而至少需要C++11。两者之间还有其他区别吗?在现代C++代码中,应该选择其中一个或另一个,为什么? 对于情况,这是GCC6.2生成的程序集: 另一方面,对于,它是: 虽然在中,我得到了相同的(优化的)程序集: 但是,s似乎有不同的行为。我在这里单独提出了一个问题。

    • 我有以下代码: 你能解释一下和以下有什么区别吗? 在这种情况下,我们有什么新发现?

    • 嗨,我对时区没有什么疑问: null 我在维基百科和许多相关网站上搜索过,但没有找到相关的解释

    • 方法接受一个供应商函数接口,该接口本质上不接受任何参数,并返回。 在哪种情况下需要使用?如果您有一个方法为什么不直接执行而不执行? 似乎并不是要将lambda表达式的执行推迟到以后的某个时间或其他时间,那么这有什么意义呢?(我认为如果它返回一个更安全的会更有用,它的从不抛出并且总是返回true...但显然它不是,它只是返回,就像)。 是不是还有什么我遗漏的不同之处?

    • 以下定义有区别吗? 如果不是,在C++11中首选哪种样式?