c++ - 难以理解 C++14 宽松的 constexpr 限制

标签 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 限制 提案,但我仍然不明白为什么这个函数返回值可以是 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) 中调用 std::maxconstexpr 被忽略 ?

最佳答案

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

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

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

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

an invocation of a constexpr function with arguments that, when substituted by function invocation substitution (7.1.5), do not produce a constant expression;

在 C++14 中,该段落被删除,我们有以下异常(exception):

an invocation of a function other than a constexpr constructor for a literal class, a constexpr function, or an implicit invocation of a trivial destructor (12.4) [ Note: Overload resolution (13.3) is applied as usual —end note ];

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

第一种情况:

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

std::vector::size未标记为 constexpr,因此属于上述异常(exception)情况。

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

A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function in all respects except that a call to a constexpr function can appear in a constant expression.

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

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

This short paper proposes to make the standard functions min and max constexpr. They were top on the list of motivating cases for al- lowing reference parameters for constexpr functions in C++11. They were forgotten after the core language change was accepted

作为引用,我们知道 125.19 节中的常量表达式,它说:

A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. An integral constant expression is a literal constant expression of integral or unscoped enumeration type. [...]

关于c++ - 难以理解 C++14 宽松的 constexpr 限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31410933/

相关文章:

函数中的 C++ const 参数

c++ - 模板参数包中的 6 个点是什么?

C++通过重载更改成员函数的访问权限

C++14 堆栈分配的共享指针

c++14 通过引用返回一个值以优化性能

c++ - QListView,如何调整到最适合的大小?

c++ - 使用编译器安装库

c++ - 强类型枚举中范围解析背后的基本原理

c++ - 如何将 std::promise 传递到线程中?通过 std::move 还是通过 std::shared_ptr?

c++ - 将满足某些条件的所有元素从一个容器移动到另一个容器,即我正在寻找某种 "move_if"