我真的找不到任何用途。我的第一个想法是,我可以使用它来实现'按合同设计'而不使用像这样的宏:
struct S
{
S(constexpr int i) : S(i) { static_assert( i < 9, "i must be < 9" ); }
S(int i); //external defintion
char *pSomeMemory;
};
但这不会编译。我想我们也可以使用它来引用同一个变量,而不需要创建额外的内存,当我们想要避免get / setter时,为了让一个成员的实例从用户只读:
class S
{
private:
int _i;
public:
const int & constexpr i = _i;
};
但以上都没有实际编译过。有人可以告诉我为什么要引入这个关键字?
答案 0 :(得分:17)
constexpr
的目标取决于具体情况:
对于对象,它表示该对象是不可变的,并且应在编译时构造。除了将操作移动到编译时而不是在运行时执行它们之外,创建constexpr
对象还有一个额外的好处,即它们在创建任何线程之前进行初始化。因此,他们的访问永远不需要任何同步。将对象声明为constexpr
的示例如下所示:
constexpr T value{args};
显然,为了实现这一点,args
需要是常量表达式。
对于函数,它表示调用函数可以导致常量表达式。 constexpr
函数调用的结果是否导致常量表达式取决于参数和函数的定义。直接的含义是函数必须是inline
(它将隐含地这样做)。此外,在这样的功能中可以做什么也存在限制。对于C ++ 11,该函数只能有一个语句,对于非构造函数,它必须是return
- 语句。这种限制在C ++ 14中得到了放松。例如,以下是constexpr
函数的定义:
constexpr int square(int value) { return value * value; }
在创建非内置类型的constexpr
对象时,相应的类型将需要constexpr
构造函数:生成的默认构造函数将不起作用。显然,constexpr
构造函数需要初始化所有成员。 constexpr
构造函数可能如下所示:
struct example {
int value;
constexpr example(int value): value(value) {}
};
int main() {
constexpr example size{17};
int array[size.value] = {};
}
创建的constexpr
值可用于预期的常量表达式。
答案 1 :(得分:7)
我认为,constexpr
是一种将两种C ++语言结合在一起的方式 - 运行时运行的语言和编译时运行的语言。编译时编程通常称为元编程。
首先是C及其宏。宏实际上是由编译器运行的小程序。他们有if语句(称为#ifdef
),变量(带#define
)。甚至整个scripting language在编译时运行。
当C ++出现时,它有C宏,仅此而已。然后是C ++模板。这些引入了运行编译时代码的不同的方式。 C ++元语言在很大程度上是功能性的,例如,允许你做loops with tail recursion。
在C ++ 11中,他们认为元编程看起来更好,所以他们引入了constexpr
。现在您可以编写也是元函数的C ++函数。在C ++ 14中它变得更好,因为对constexpr函数的限制已经放宽了。
答案 2 :(得分:4)
以下是Alex Allain在他的&#34; Constexpr - C ++ 11中的广义常量表达式中所提出的观点的总结,&#34;详细信息 constexpr
的有用性:
constexpr
说明符,函数或变量的值可以在编译时。 constexpr
说明符的另一个好处是它可以用函数constexpr
也会使您的模板元编程受益。有效提高效率:
常量表达式......允许某些计算在编译时进行,字面意思是在代码编译时,而不是在程序本身运行时。 (Allain 2)
性能优势:如果某些事情可以在编译时完成,那么它将完成一次,而不是每次程序运行时
其他好处:
然后可以在仅允许编译时常量表达式的情况下使用这些变量和函数。对象声明中使用的constexpr说明符意味着const。函数声明中使用的constexpr说明符暗示内联。(CPP 1)
constexpr
功能规则:
- 必须包含单一退货声明(少数例外)
- 它只能调用其他constexpr函数
- 它只能引用constexpr全局变量(Allain 6)
醇>
constexpr
构造函数的规则:
- 其每个参数必须是文字类型
- 该类必须没有虚拟基类
- 构造函数不能具有function-try-block(CPP 6)
醇>
Allain,Alex,&#34; Constexpr - C ++中的广义常量表达式11&#34;,未指定日期,&#34; http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr.html&#34;
CPP,&#34; Constexpr Specifier&#34;,2014年12月16日,http://en.cppreference.com/w/cpp/language/constexpr
编辑:抱歉,我觉得自己似乎是这些要点的作者,所以我已经纠正了自己,更改了各个部分,并添加了引文来避免剽窃。
答案 3 :(得分:0)
答案&#34;有人可以告诉我为什么要引入constexpr关键字吗?&#34;
Modern C ++支持两种类型的不变性。
1)const
2)constexpr。
constexper将在编译时进行评估。它用于指定constness并允许将数据放置在可能已损坏的内存中。
示例1:
void UseConstExpr(int temp)
{
// This code snippet is OK
constexpr int y = max + 300;
std::cout << y << std::endl;
// This code snippet gives compilation error
// [ expression must have a constant value]
constexpr int z = temp + 300;
}
示例2:
int addVector(const std::vector<int>& inVect)
{
int sum = 0;
for ( auto& vec : inVect)
{
sum += vec;
}
std::cout << sum << std::endl;
return sum;
}
int main()
{
// vInt is not constant
std::vector<int> vInt = { 1,2,3,4,5,6 };
// This code snippet is OK
// because evaluated at run time
const int iResult = addVector(vInt);
// Compiler throws below error
// function call must have a constant value in a constant expression
// because addVector(vInt) function is not a constant expression
constexpr int iResult = addVector(vInt);
return 0;
}
注意:上面的源代码是在VS2015上编译的