有时它有时不起作用:
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
}
有没有办法破解上面的例子?即强制编译器从构造函数参数中推断出模板参数。
将来是否会修复,或者有充分理由不这样做吗?
编译器可以推断出模板参数的一般规则是什么?
答案 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;
}