编译器可以推断出模板参数吗?

时间:2009-04-28 12:21:12

标签: c++ templates

有时它有时不起作用:

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
}

有没有办法破解上面的例子?即强制编译器从构造函数参数中推断出模板参数。

将来是否会修复,或者有充分理由不这样做吗?

编译器可以推断出模板参数的一般规则是什么?

3 个答案:

答案 0 :(得分:54)

当可以从模板参数中推导出参数类型时,可以推断函数模板的模板参数

所以可以在这里推断:

template <typename T>
void f(T t);

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

但不在这里:

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

而不是类模板

因此,解决问题的通常方法是创建一个包装函数,类似于标准库函数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); }

然后调用auto a = MakeMyClass(5);来实例化该类。

答案 1 :(得分:8)

答案 2 :(得分:0)

在C ++ 17中,可以使用auto推断某些类型,尽管仍然需要在此处指定模板参数:

#include <iostream> 
#include <string>

template <class T1,class T2>   
auto print_stuff(T1 x, T2 y) 
{ 
    std::cout << x << std::endl;
    std::cout << y << std::endl;
}

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

使用gcc中的-fconcepts标志,可以推断参数,尽管这还不是C ++标准的一部分:

#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; 
}