How are template arguments resolved / deduced?

During training and experimenting with templates, I came across something that I could not fully understand.

class sample { public: sample(int a = 0) {} }; template <typename T1,typename T2> void add(T1 a) // Replace T1 with T2 resolves compilation error. {} int main() { add<sample>(3); return 0; } 

The above code leads to a compilation error (both 03 and C ++ 0x). But when I change the type of the add argument from T1 to T2, that's fine. With nm, the prototype created is add (sample, int) [T1 = sample, T2 = int]. Why does compilation fail with T1 as the argument type, but not T2?

+6
source share
2 answers

There are two ways to specify template arguments: explicitly or implicitly.

This will be explicit:

 template<typename T> void do_something(T value) {}; do_something<float>(6); // T is float 

This will be implicit:

 int x; do_something(x); // since first argument is T and x is int, T is int 

In your case:

 template <typename T1,typename T2> void add(T1 a); add<sample>(3); // T1 is explcitly sample, T2 is unknown 

Case 2:

 template <typename T1,typename T2> void add(T2 a); add<sample>(3); // T1 is explcitly sample, T2 is implicitly int 
+6
source

This is because the sample class can be implicitly created from int . And so, when you specify <sample> as a type argument, int matches the first parameter of type <sample> , implicitly , but T2 then undefined because it can't be output to any type.

This does not happen in the second case, because then you partially specify the types: <sample> indicates the type T1 , and then int can be inferred for T2 , and the types of patterns are all inferred. Even if all types are not used, this is normal.

+1
source

All Articles