我发现了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
时会被忽略?
答案 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函数的参考参数。他们 在核心语言变更被接受后被遗忘
作为参考,我们知道1
和2
是5.19
部分中的常量表达式,其中包含:
文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型。一个 integral constant expression是整数或未整数枚举类型的文字常量表达式。 [...]