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

时间:2015-07-14 15:28:06

标签: c++ c++11 c++14 constexpr

我发现了std::max函数的新C ++ 14签名:

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)

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

示例:

constexpr

在(1)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) 中调用std::max时会被忽略?

1 个答案:

答案 0 :(得分:11)

基本问题与轻松的constexpr规则没有直接关系,如果参数是常量表达式,constexpr函数只是一个常量表达式。在你的第二个案例中:

int array[std::max(1,2)];

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

在这种情况下,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()];

std::vector::size未标记为constexpr,因此属于上述引用的例外情况。

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

  

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

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

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

  

这篇简短的论文建议将标准函数设为min和max   constexpr。他们在激励案例中名列前茅   降低C ++ 11中constexpr函数的参考参数。他们   在核心语言变更被接受后被遗忘

作为参考,我们知道125.19部分中的常量表达式,其中包含:

  

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