Reputation: 8487
I wrote the following code for which template argument deduction fails :
template<int>
struct num {};
template<int m>
void match(num<2*m>) {
}
int main()
{
match(num<2>());
return 0;
}
I know from a gut feeling that the compiler can't deduce the correct m
, but I want to understand the theoretical underpinnings for why it fails. Can someone elucidate?
Upvotes: 5
Views: 963
Reputation: 320361
Well, you are basically asking the compiler to solve the equation 2 * m == 2
for you in order to determine template argument m
for match
. Compiler does not solve equations during template argument deduction, regardless of how simple and unambiguous they are.
The language specification in 14.8.2.4/14 (C++03), 14.8.2.5/16 (C++11) covers your situation and has a similar example
14 If, in the declaration of a function template with a non-type template-parameter, the non-type template-parameter is used in an expression in the function parameter-list, the corresponding template-argument must always be explicitly specified or deduced elsewhere because type deduction would otherwise always fail for such a template-argument.
template<int i> class A { /* ... */ };
template<short s> void g(A<s+1>);
void k() {
A<1> a;
g(a); //error: deduction fails for expression s+1
g<0>(a); //OK
}
As to why it is done that way... I think it is pretty obvious that in general case the problem of solving a mathematical equation is too complicated. It can also lead to ambiguous solutions or to solutions that don't belong to the expected domain. For example, what would you expect the compiler to deduce for match(num<3>())
?
Upvotes: 6