GCC constexpr constexpr 函数中的 lambdas 和编译时的评估
GCC constexpr lambdas in constexpr functions and evaluation in compile time
代码先,我们有下面一段代码,用来在编译时累加一个constexpr std::array
:
template <typename T, std::size_t N, typename O>
constexpr T compile_time_accumulator(const std::array<T, N> const &A, const std::size_t i, const O& op, const T initialValue)
{
return (i < N)
? op(A[i], compile_time_accumulator(A, i + 1, op, initialValue))
: initialValue;
}
以及以下 test/varify 它的代码示例(即,它在编译时求值):
constexpr std::array<int, 4> v {{4, 5, 6, 7}};
std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, std::plus<int>())>::value
<< std::endl;
现在,如果将运算符 std::plus<int>
更改为 constexpr
lambda:
constexpr auto lambda_plus = [] (int x, int y) { return x + y; };
并像下面这样称呼它:
constexpr std::array<int, 4> v {{4, 5, 6, 7}};
std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, lambda_plus)>::value << std::endl;
^^^^^^^^^^^
我得到一个错误,lambda 不是 constexpr
:
call to non-constexpr function ''
现在做一点 research 我发现 constexpr
lambda 还不支持。
问:
为什么如果 constexpr
lambda 不受支持,我们可以首先定义 constexpr
lambda?
编辑:
clang 似乎不接受 code。那么哪个编译器是正确的?
C++11 允许非常有限的 constexpr
定义,而 C++14 有一长串不是 constexpr
From n4296 (release candidate for C++14) 5.20.2.6
5.20 Constant expressions [expr.const]
2 A conditional-expression e is a core constant expression unless the
evaluation of e, following the rules of the abstract machine (1.9),
would evaluate one of the following expressions:
2.6) — a lambda-expression (5.1.2);
所以答案是 lambda 不正确,所以编译器一定是错误的。
根据 [expr.const]/(2.6),代码确实格式错误; lambda 还不允许出现在常量表达式中,尽管 corresponding proposal 正在流通。 GCC 在接受 lambda_plus
的声明时不正确。
代码先,我们有下面一段代码,用来在编译时累加一个constexpr std::array
:
template <typename T, std::size_t N, typename O>
constexpr T compile_time_accumulator(const std::array<T, N> const &A, const std::size_t i, const O& op, const T initialValue)
{
return (i < N)
? op(A[i], compile_time_accumulator(A, i + 1, op, initialValue))
: initialValue;
}
以及以下 test/varify 它的代码示例(即,它在编译时求值):
constexpr std::array<int, 4> v {{4, 5, 6, 7}};
std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, std::plus<int>())>::value
<< std::endl;
现在,如果将运算符 std::plus<int>
更改为 constexpr
lambda:
constexpr auto lambda_plus = [] (int x, int y) { return x + y; };
并像下面这样称呼它:
constexpr std::array<int, 4> v {{4, 5, 6, 7}};
std::cout << std::integral_constant<int, compile_time_accumulator(v, 42, lambda_plus)>::value << std::endl;
^^^^^^^^^^^
我得到一个错误,lambda 不是 constexpr
:
call to non-constexpr function ''
现在做一点 research 我发现 constexpr
lambda 还不支持。
问:
为什么如果 constexpr
lambda 不受支持,我们可以首先定义 constexpr
lambda?
编辑:
clang 似乎不接受 code。那么哪个编译器是正确的?
C++11 允许非常有限的 constexpr
定义,而 C++14 有一长串不是 constexpr
From n4296 (release candidate for C++14) 5.20.2.6
5.20 Constant expressions [expr.const]
2 A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
2.6) — a lambda-expression (5.1.2);
所以答案是 lambda 不正确,所以编译器一定是错误的。
根据 [expr.const]/(2.6),代码确实格式错误; lambda 还不允许出现在常量表达式中,尽管 corresponding proposal 正在流通。 GCC 在接受 lambda_plus
的声明时不正确。