Reputation: 42899
Code first, we have the following piece of code that is used to accumulate a constexpr std::array
in compile time:
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;
}
and the following code example to test/varify it (i.e., that it evaluates in compile time):
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;
Now if change the operator std::plus<int>
with a constexpr
lambda:
constexpr auto lambda_plus = [] (int x, int y) { return x + y; };
and call it like below:
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;
^^^^^^^^^^^
I get an error, that lambda is not constexpr
:
call to non-constexpr function ''
Now doing a litle research I discovered that constexpr
lambdas aren't support yet.
Why if constexpr
lambdas aren't supported, we are allowed to define a constexpr
lambda in the first place?
Edit:
It seems that clang doesn't accep the code. So which compiler is right?
Upvotes: 0
Views: 472
Reputation: 16089
C++11 allowed a very limited amount definition of a constexpr
while C++14 has a long list of is not a 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);
So the answer is that lambda's are not OK so the compiler must be wrong.
Upvotes: 3
Reputation: 60979
The code is indeed ill-formed as per [expr.const]/(2.6); lambdas aren't yet allowed in constant expressions, though a corresponding proposal is in circulation. GCC is incorrect in accepting lambda_plus
's declaration.
Upvotes: 3