问题
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?
回答1:
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:
template <> struct W<137> {
using T = Y<0>; // Not Y<137>
};
Now, suppose that you call foo
, passing in a Y<0>
as the argument. What should the compiler deduce as the numeric value of N
? It could be zero, since W<0>
defines T
as Y<0>
. But it could just as easily be 137, since W<137>
defines T
as Y<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.
来源:https://stackoverflow.com/questions/47117339/template-argument-deduction-substitution-failed-when-using-typename-argument