理解C++14时出现问题放宽了constexpr限制

Trouble understanding C++14 Relaxed constexpr restrictions

本文关键字:constexpr 限制 问题 C++14 理解      更新时间:2023-10-16

我发现了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限制的建议,但我仍然不明白为什么这个函数返回值可以是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)

在(1(constexpr中调用std::max时被忽略?

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

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

这是因为整型文字实际上是常量表达式。

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

使用参数调用constexpr函数,当被函数调用替换(7.1.5(替换,不要产生一个常量表达式;

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

调用的constexpr构造函数以外的函数literal类、constexpr函数或对平凡析构函数(12.4([注:重载分辨率(13.3(为照常使用--尾注];

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

在第一种情况下:

int array[std::max(a.size(), b.size()];

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

还要注意的是,在7.1.5[dcl.constexpr]部分中,我们有以下内容:

对constexpr函数的调用产生的结果与对除了对constexpr函数的调用可以出现在常量表达式中。

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

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

本文提出将标准函数设为min和maxconstexpr。他们在阿尔的激励案例列表中名列前茅-降低了C++11中constexpr函数的参考参数。他们在接受核心语言更改后被遗忘

作为参考,我们知道125.19节中的常数表达式,其中写道:

文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型。一整型常量表达式是整型或无范围枚举类型的文字常量表达式。[…]