I have the following code, which defines a template struct W
that exports a type T
that's based on the template argument to W
:
#include <iostream>
using namespace std;
template <unsigned N>
struct Y {};
template <unsigned N>
struct W {
using T = Y<N>;
};
I then defined this template function that looks at this type T
:
template <unsigned N>
void foo (const typename W<N>::T& in) {
//--
}
The problem here is that if I try calling this function from main
using one of the types exported as T
, it doesn't compile. For example, if I write
int main() {
Y<2> y;
foo(y);
return 0;
}
I get a compiler error that says
template argument deduction/substitution failed:
couldn't deduce template parameter
What's going on here?
The reason that the C++ compiler can't figure this out has to do with template specialization. For example, suppose that you specialize the
W
struct template like this:Now, suppose that you call
foo
, passing in aY<0>
as the argument. What should the compiler deduce as the numeric value ofN
? It could be zero, sinceW<0>
definesT
asY<0>
. But it could just as easily be 137, sinceW<137>
definesT
asY<0>
as well.More generally, C++ will never try to deduce the type of a template argument to an outer template based on one of the inner types, for precisely the reason shown above.