Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are templates arguments resolved/deduced?

Tags:

c++

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?

like image 891
DIVAKAR VENKATRAMANI Avatar asked Dec 28 '15 11:12

DIVAKAR VENKATRAMANI


People also ask

What is a template argument?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

How many template arguments are there?

1) A template template parameter with an optional name. 2) A template template parameter with an optional name and a default. 3) A template template parameter pack with an optional name.

What is template argument deduction?

Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.

Can there be more than one argument to template?

Can there be more than one argument to templates? Yes, like normal parameters, we can pass more than one data type as arguments to templates.


2 Answers

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
like image 125
zvone Avatar answered Oct 07 '22 08:10

zvone


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.

like image 29
JBL Avatar answered Oct 07 '22 06:10

JBL