什么是'constexpr'有用?

AnA*_*ons 15 c++ compile-time language-lawyer c++11

我真的找不到任何用途.我的第一个想法是,我可以使用它来实现'按合同设计',而不使用像这样的宏:

struct S
{   
    S(constexpr int i) : S(i) { static_assert( i < 9, "i must be < 9" ); }

    S(int i); //external defintion

    char *pSomeMemory;
};
Run Code Online (Sandbox Code Playgroud)

但这不会编译.我想我们也可以使用它来引用同一变量,而不需要创建额外的内存,当我们想要避免get/setters时,为了使用户的一个成员的实例是只读的:

class S
{  
private:
    int _i;

public:
    const int & constexpr i = _i;
};
Run Code Online (Sandbox Code Playgroud)

但以上都没有实际编译过.有人可以告诉我为什么要引入这个关键字?

Die*_*ühl 19

目标constexpr取决于具体情况:

  1. 对于对象,它表示该对象是不可变的,并且应该在编译时构造.除了将操作移动到编译时而不是在运行时执行它们创建constexpr对象之外还有一个额外的好处,即它们在创建任何线程之前进行初始化.因此,他们的访问永远不需要任何同步.声明对象的示例constexpr如下所示:

    constexpr T value{args};
    
    Run Code Online (Sandbox Code Playgroud)

    显然,为了工作,args需要是常量表达式.

  2. 对于函数,它表示调用函数可以导致常量表达式.constexpr函数调用的结果是否导致常量表达式取决于参数和函数的定义.直接的含义是函数必须是inline(它将隐含地这样做).此外,在这样的功能中可以做什么也存在限制.对于C++ 11,该函数只能有一个语句,对于非构造函数,它必须是a- returnstatement.这种限制在C++ 14中得到了放松.例如,以下是constexpr函数的定义:

    constexpr int square(int value) { return value * value; }
    
    Run Code Online (Sandbox Code Playgroud)

在创建constexpr非内置类型的对象时,相应的类型将需要constexpr构造函数:生成的默认构造函数将不起作用.显然,constexpr构造函数需要初始化所有成员.一个constexpr构造函数看起来是这样的:

struct example {
    int value;
    constexpr example(int value): value(value) {}
};

int main() {
    constexpr example size{17};
    int array[size.value] = {};
}
Run Code Online (Sandbox Code Playgroud)

创建的constexpr值可以在预期的常量表达的任何地方使用.

  • 不,对于函数,它表示函数*call*是调用替换时所说的常量表达式.(参数可以是常量表达式,但函数调用不一定是.) (2认同)

zmb*_*mbq 7

我看待它constexpr的方式是将两种C++语言结合在一起的方法 - 在运行时运行的语言和在编译时运行的语言.编译时编程通常称为元编程.

首先是C,带有宏.宏实际上是由编译器运行的小程序.他们有if语句(称为#ifdef),变量(带#define).甚至还有一种在编译时运行的完整脚本语言.

当C++出来时,它有C宏,仅此而已.然后是C++模板.这些介绍了运行编译时代码的不同方法.例如,C++元语言在很大程度上是功能性的,允许您使用尾递归来执行循环.

在C++ 11中,他们认为元编程看起来更好,所以他们已经介绍过了constexpr.现在您可以编写也是元函数的C++函数.在C++ 14中它变得更好,因为对constexpr函数的限制已经放宽了.


Irr*_*son 5

以下是 Alex Allin 在他的“Constexpr - C++11 中的通用常量表达式”中提出的观点的摘要,其中详细介绍了以下内容的用处constexpr

  • 首先,通过constexpr说明符,函数或变量的值可以是在编译​​时。
  • 说明符的另一个好处constexpr是它可以用函数替换宏
  • constexpr也将有利于您的模板元编程。

对效率的好处:

常量表达式...允许在编译时进行某些计算,实际上是在代码编译时而不是在程序本身运行时进行。(阿兰2)

性能优势:如果某件事可以在编译时完成,那么它将完成一次,而不是每次程序运行时完成

其他福利:

然后可以在仅允许编译时常量表达式的情况下使用此类变量和函数。对象声明中使用的 constexpr 说明符隐含 const。函数声明中使用的 constexpr 说明符意味着内联。(CPP 1)

函数规则constexpr

  1. 它必须由单个 return 语句组成(有一些例外)
  2. 它只能调用其他 constexpr 函数
  3. 它只能引用 constexpr 全局变量 (Allain 6)

构造函数规则constexpr

  1. 它的每个参数必须是文字类型
  2. 该类必须没有虚拟基类
  3. 构造函数不得有函数 try 块 (CPP 6)

引文

Allin、Alex,“Constexpr - C++11 中的通用常量表达式”,未指定日期,“ http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr .html

CPP,“Constexpr 说明符”,2014 年 12 月 16 日,http://en.cppreference.com/w/cpp/language/constexpr


编辑:抱歉,我的错让这些观点看起来像是我的作者,所以我纠正了自己,更改了各个部分,并添加了引用以避免抄袭。

  • 来源 - http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr.html (2认同)
  • 考虑重新格式化您的帖子以表明您**直接引用其他人**。就目前情况而言,大部分内容读起来就好像您是作者一样,但实际上外部链接中的内容是逐字逐句的。有些人可能认为这是抄袭。 (2认同)