This used to work some weeks ago:
template
T tfunc()
{
return t + 10;
}
template
constexpr T
I get the feeling that constexpr
must also be valid in a 'runtime' context, not just at compile-time. Marking a function as constexpr
encourages the compiler to try to evaluate it at compile-time, but the function must still have a valid run-time implementation.
In practice, this means that the compiler doesn't know how to implement this function at runtime:
template
constexpr T func(T t)
{
return tfunc();
}
A workaround is to change the constructor such that it takes its t
parameter as a normal parameter, not as a template parameter, and mark the constructor as constexpr
:
template
constexpr T tfunc(T t)
{
return t + 10;
}
template
constexpr T func(T t)
{
return tfunc(t);
}
There are three levels of 'constant-expression-ness':
constexpr
// Something that may be a constant-expressionYou can't really convert items that are low in that list into something that is high in that list, but obviously the other route it possible.
For example, a call to this function
constexpr int foo(int x) { return x+1; }
isn't necessarily a constant-expression.
// g++-4.6 used in these few lines. ideone doesn't like this code. I don't know why
int array[foo(3)]; // this is OK
int c = getchar();
int array[foo(c)]; // this will not compile (without VLAs)
So the return value from a constexpr
function is a constant expression only if all the parameters, and the implementation of the function, can be completed at executed at compile-time.