Łukasz Lew
Łukasz Lew

Reputation: 50348

When a compiler can infer a template parameter?

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?

Upvotes: 40

Views: 19701

Answers (3)

Anderson Green
Anderson Green

Reputation: 31850

Since C++20, it is possible to infer the types of function parameters using auto:

#include <iostream> 
#include <string>

auto print_stuff(auto x, auto y) 
{ 
    std::cout << x << std::endl;
    std::cout << y << std::endl;
}

int main() 
{ 
    print_stuff(3,"Hello!");
    print_stuff("Hello!",4);
    return 0; 
}

Upvotes: 1

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 248289

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.

Upvotes: 64

dirkgently
dirkgently

Reputation: 111336

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

Upvotes: 8

Related Questions