理解C++14时出现问题放宽了constexpr限制
Trouble understanding C++14 Relaxed constexpr restrictions
我发现了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函数的参考参数。他们在接受核心语言更改后被遗忘
作为参考,我们知道1
和2
是5.19
节中的常数表达式,其中写道:
文字常量表达式是文字类型的prvalue核心常量表达式,但不是指针类型。一整型常量表达式是整型或无范围枚举类型的文字常量表达式。[…]
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 用C++20 fmt限制结果的总大小
- 多成员Constexpr结构初始化
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 当用户超过按钮点击限制时报告
- 为什么constexpr的性能比正常表达式差
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何在c++中限制尝试次数
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 绕过 constexpr 的重新解释演员限制
- Constexpr深度限制与clang (fconstexpr-depth似乎不起作用)
- 在常量初始化器中调用constexpr构造函数的限制
- 理解C++14时出现问题放宽了constexpr限制
- constexpr计算量的实际限制