为了账号安全,请及时绑定邮箱和手机立即绑定

“警察”和“警察”的区别

“警察”和“警察”的区别

C++
湖上湖 2019-07-02 14:56:29
“警察”和“警察”的区别有什么区别constexpr和const?我什么时候才能用其中之一?我什么时候可以使用两者,我应该如何选择一个?
查看完整描述

3 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

基本意义和句法

这两个关键字都可以用于对象和函数的声明。应用于对象这是:

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

  • constexpr声明一个适合在标准调用的对象中使用的对象常数表达式..但请注意constexpr不是唯一的办法。

适用于功能基本的区别是:

  • const只能用于非静态成员函数,一般不能用于函数.它保证成员函数不会修改任何非静态数据成员。

  • constexpr既可用于成员函数,也可用于非成员函数,也可用于构造函数。它声明该函数适合用于常数表达式..只有当函数满足某些条件(7.1.5/3,4)时,编译器才会接受它,最重要的是(†):

    • 函数体必须是非虚拟的,并且非常简单:除了类型防御和静态断言之外,只有一个

      return

      允许陈述。在构造函数的情况下,只允许初始化列表、类型防御和静态断言。(

      = default

      = delete

      但也是允许的。)
    • 从C+14开始,规则就更宽松了,从那时起,在一个函数中允许这样做:

      asm

      声明,a

      goto

      语句,具有其他标签的语句。

      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}

我什么时候可以/应该同时使用,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;}

这里,NP声明为地址常量表达式,即本身为常量表达式的指针。(当通过将地址运算符应用于静态/全局常量表达式生成地址时,这是可能的。)在这里,都是constexprconst需要:constexpr总是引用被声明的表达式(在这里)NP),同时constint(它声明了一个指向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功能。


查看完整回答
反对 回复 2019-07-02
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

const申请变量,和防止它们被修改在你的密码里。

constexpr告诉编译器表达结果编译时间常数,因此可以在数组长度之类的地方使用,将const变量等链接Oli给出了很多很好的例子。

基本上,它们是两个完全不同的概念,可以(而且应该)一起使用。


查看完整回答
反对 回复 2019-07-02
  • 3 回答
  • 0 关注
  • 436 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信