Reputation: 237
While learning and experimenting with templates, I came across something I could not grasp fully.
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 results in compilation error (both 03 and c++0x). But when I change the argument type of add from T1 to T2, it is ok. With nm, the prototype created is add(sample,int) [T1 = sample, T2 = int]. Why does the compilation fail with T1 as the argument type but not T2?
Upvotes: 6
Views: 102
Reputation: 19352
There are two way to specify template arguments: explicitly or implicitly.
This would be explicit:
template<typename T>
void do_something(T value) {};
do_something<float>(6); // T is float
This would 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
Upvotes: 6
Reputation: 12907
This is because the sample
class can be implicitly created from an int
. And thus, when you specify <sample>
as a type argument, the int
matches the first parameter, of type <sample>
, implicitly, but T2
is then undefined as it can't be deduced to any type.
This doesn't happen in the second case, because then you specify partially the types: <sample>
specifies the type of T1
, and an int
can then be deduced for T2
, and the template types are all deduced. Even if all the types aren't used, this is fine.
Upvotes: 1