Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When a compiler can infer a template parameter?

Tags:

c++

templates

Sometimes it works sometimes not:

template <class T>  void f(T t) {}  template <class T> class MyClass { public:   MyClass(T t) {} };  void test () {   f<int>(5);   MyClass<int> mc(5);   f(5);   MyClass mc(5); // this doesn't work } 

Is there a way to hack around the example above? I.e. force the compiler to infer the template parameter from constructor parameter.

Will this be fixed in the future, or is there a good reason not to?

What is the general rule when compiler can infer template parameter?

like image 451
Łukasz Lew Avatar asked Apr 28 '09 12:04

Łukasz Lew


People also ask

What can be a template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Why do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

What are templates and how does the compiler interpret them?

A template is a pattern for creating code. When the compiler sees the definition of a template it makes notes about that pattern.

Can a template be a template parameter?

Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.


2 Answers

Template parameters can be inferred for function templates when the parameter type can be deduced from the template parameters

So it can be inferred here:

template <typename T> void f(T t);  template <typename T> void f(std::vector<T> v); 

but not here:

template <typename T> T f() {   return T(); } 

And not in class templates.

So the usual solution to your problem is to create a wrapper function, similar to the standard library function std::make_pair:

  template <class T>     class MyClass {     public:         MyClass(T t) {}         void print(){             std::cout<<"try MyClass"<<std::endl;         }     };      template <typename T>     MyClass<T> MakeMyClass(T t) { return MyClass<T>(t); } 

and then call auto a = MakeMyClass(5); to instantiate the class.

like image 55
jalf Avatar answered Sep 28 '22 00:09

jalf


Read up on Template Argument Deduction (and ADL or Koenig lookup).

like image 35
dirkgently Avatar answered Sep 28 '22 02:09

dirkgently