I tried to find a solution for the problem of the question C++ template non-type parameter type deduction, which does not involve a template parameter to call f, but implicitly chooses the correct type for the template parameter.
Since constexpr should guarantee that a function only contains compile time constants, and is evaluated at compile time (at least thats what i think it does), i thought it might be the solution for this issue.
So i came up with this:
template <class T, T VALUE> void f() {}
//first i tried this:
template <class T> auto get_f(T t) -> decltype( &f<T,t> ) { return f<T,t>; }
//second try:
template <class T> constexpr void (&get_f( T t ))() { return f<T,t>; }
int main()
{
get_f(10)(); //gets correct f and calls it
}
first version generates following error:
error: use of parameter 't' outside function body
which is really confusing, since the usage of parameters in the decltype statement of a trailing return type should be ok?
second version generates following error:
error: invalid initialization of non-const reference of type 'void (&)()'
from an rvalue of type '<unresolved overloaded function type>'
which is kinda confusing, since i fully qualified f in get_f.
I would expect this kind of error messages if i did not have the constexpr. So do i have a false understanding of what constexpr does, or is the C++0x implementation of GCC flawed for this case ?
I am using GCC 4.6.2
A
constexprfunction can be used in a constant expression context, but is not restricted to one. In this respect they are different from a metafunction and a regular function. Consider the problem of returning the successor of an integer:constexprhas other usages (e.g. constructors) but when it comes toconstexprfunctions this is the gist of it: some functions should be available in both runtime and constant contexts because some computations are available in both. It’s possible to computei + 1whetheriis a compile-time constant or is extracted fromstd::cin.This means that inside the body of a
constexprfunction the parameters are not themselves constant expressions. So what you are attempting is not possible. Your function can’t deal withand the violation happens here:
Since
tis not a constant expression according to the rules of the language (no matter what, even if you actually only pass constant expressions in), it can’t appear as the second template parameter off.(And in the larger picture it means that no, you can’t use argument deduction from function templates to conveniently pass a non-type parameter to a class template.)