Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template argument deduction failed

Tags:

c++

templates

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?

like image 826
keveman Avatar asked Nov 28 '12 02:11

keveman


People also ask

What is template argument deduction in C++?

Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.

Can there be more than one argument to template?

Yes, like normal parameters, we can pass more than one data type as arguments to templates.

What is Typename C++?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.


1 Answers

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>())?

like image 83
AnT Avatar answered Sep 22 '22 02:09

AnT