I would like to write a template that can deconstruct a type into a template with non-type type template parameters along with its non-type arguments. For example, it will deconstruct Array<5>
into template<int> Array
and 5
, but it will work in the general case for any type of template parameters of a non-type type (integral types, pointers, member pointers, etc.).
First try using the template specialization:
template<typename T> struct foo { enum { n = 1 }; }; template<int x> struct bar { enum { n = x }; }; template<typename T, template<T> class X, T x> struct foo< X<x> > { enum { n = x }; };
Clang 3.1 says:
test145.cpp:6:8: warning: class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used struct foo< X<x> > { enum { n = x }; }; ^~~~~~~~~~~ test145.cpp:5:19: note: non-deducible template parameter 'T' template<typename T, template<T> class X, T x> ^ 1 warning generated.
Second attempt, with function template:
template<typename T, T x> struct box { static constexpr T value() { return x; } }; template<typename T, template<T> class X, T x> box<T, x> foo(X<x>); template<int> struct asdf { }; int main(int, char**) { return decltype(foo(*(asdf<9>*)0))::value(); }
Klang says:
test150.cpp:12:41: error: no matching function for call to 'foo' int main(int, char**) { return decltype(foo(*(asdf<9>*)0))::value(); } ^~~ test150.cpp:8:11: note: candidate template ignored: couldn't infer template argument 'T' box<T, x> foo(X<x>); ^ 1 error generated.
GCC 4.7 talks about such things.
Is this a fundamental limitation?
Bonus question: if so, is there any way to handle all the infinite possibilities in a finite amount of code, even if it is less simple and general code? (This makes pointers difficult, for example: for the same reason that you cannot write template<T>
, I don't think you could write template<T*>
.)
Please do not ask why I ask.