Reputation: 4850
Consider this code:
#include <array>
template < int... Ints >
constexpr std::array<int,sizeof...(Ints)> theIntArray = {Ints...};
template < size_t NN >
constexpr void test(const std::array<int,NN>& xx)
{
theIntArray<xx[0]>;
}
constexpr std::array<int,2> aa = {10,20};
int main()
{
theIntArray<aa[0]>; // passes
test(aa); // FAILS ?!
return 0;
}
In the main()
function the first line passes while the second line fails with a strange error message:
error: ‘* & xx’ is not a constant expression
note: in template argument for type ‘int’
I am using gcc-7.0.1 and you can find live example here.
Is this according to the standard or it is a bug? What makes the second line fail while the first line passes?
Upvotes: 1
Views: 214
Reputation: 70556
The difference is that constexpr function parameter do not exist. That is, you cannot do
constexpr auto fun(int x) {
constexpr y = x;
return y;
}
and neither can you use a function parameter xx[0]
as a non-type template-parameter inside the function. It's different for aa[0]
because that is evaluated outside a function.
The only way to do what you want, is to make the function parameter a non-type template parameter. To do that, see the answer by @Yakk where he uses a const-reference to a constexpr
array as a non-type template parameter.
Upvotes: 1
Reputation: 275966
All constexpr
functions must be valid with both a constexpr
and non-constexpr
arguments. Or, in short, the arguments of a constexpr
function are not constexpr
within the body, but if they are constexpr
outside the function body, certian calculations depending on them may be constexpr
on return from the function.
theIntArray<xx[0]>;
this is only valid syntax if xx[0]
is constexpr
, but within the function body xx
is not constexpr
.
template < size_t NN, std::array<int,NN> const& xx >
constexpr void test()
{
theIntArray<xx[0]>;
}
Upvotes: 2