无法理解C++ 14轻松的constexpr限制

Ale*_*man 6 c++ constexpr c++11 c++14

我遇到了新的C++ 14签名std::max功能:

template< class T > 
const T& max( const T& a, const T& b ); // (C++11)

template< class T > 
constexpr const T& max( const T& a, const T& b );// (C++14)
Run Code Online (Sandbox Code Playgroud)

我已经阅读了关于C++ 14的轻松constexpr限制提议,但我仍然不明白为什么这个函数的返回值可以是constexpr

例:

std::vector<int> a, b;
//This does not compile but as my understadnding of `constexpr` this should
int array[std::max(a.size(), b.size()]; (1)
//This is trivial use that does compile
int array[std::max(1,2)]; (2)
Run Code Online (Sandbox Code Playgroud)

当忽略std::max(1)中的呼叫时constexpr

Sha*_*our 11

基本问题与宽松的constexpr规则没有直接关系,如果参数是常量表达式,constexpr函数只是一个常量表达式.在你的第二种情况:

int array[std::max(1,2)];
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为整数文字确实是常量表达式.

在这种情况下,C++ 11更具体,5.19 [expr.const]部分中的C++ 11标准草案列出了子表达式不被视为常量表达式并包含以下内容的情况:

调用带有参数的constexpr函数,当被函数调用替换(7.1.5)替换时,不生成常量表达式;

在C++ 14中删除了这一段,我们有以下例外:

调用除constexpr构造函数以外的函数,用于文字类,constexpr函数或简单析构函数的隐式调用(12.4)[注意:重载决策(13.3)应用为常规 - 结束注释];

并且我们必须使用关于参数(子表达式)的其余规则.

在第一种情况下:

int array[std::max(a.size(), b.size()];
Run Code Online (Sandbox Code Playgroud)

std :: vector :: size未标记为constexpr,因此它属于上述引用的异常.

另请注意,在7.1.5 [dcl.constexpr]部分中,我们有以下内容:

对constexpr函数的调用产生与在所有方面调用等效的非constexpr函数相同的结果,除了对constexpr函数的调用可以出现在常量表达式中.

将参数传递给constexpr函数并非常量表达式只意味着该表达式不适用于需要常量表达式的上下文中.

正如dyp所指出的那样,std::max由于各种问题可能包括委员会保守和有限的时间,因此在C++ 11中没有成为constexpr ,我们可以看到N3039中涉及的一些问题.它被遗忘了,看到N3856说:

这篇简短的论文提出了使标准函数min和max constexpr.它们是在C++ 11中为constexpr函数提供参考参数的激励案例中的首选.在核心语言变更被接受后,他们被遗忘了

作为参考,我们知道1并且2是来自部分的常量表达,5.19其中说:

文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型.整数常量表达式是整数或未整数枚举类型的文字常量表达式.[...]