DIVAKAR VENKATRAMANI
DIVAKAR VENKATRAMANI

Reputation: 237

How are templates arguments resolved/deduced?

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

Answers (2)

zvone
zvone

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

JBL
JBL

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

Related Questions