为什么编译器无法自动找到匹配项并进行实例化?
template <typename T1, typename T2>
struct A
{
A( const T1& t1_, const T2& t2_ )
: t1( t1_ ), t2( t2_ )
{}
T1 t1;
T2 t2;
};
int main()
{
double d = 5.2;
std::string s( "hi" );
A a( d, s ); // this doesn't compile (gcc)
A<double, std::string> a1(d, s); // OK
}
从gcc编译错误: 错误:在&#39; a&#39;之前缺少模板参数 错误:预期&#39;;&#39;之前&#39; a&#39;
答案 0 :(得分:2)
模板参数推导仅适用于对函数模板的调用。如果你的例子之类的内容被允许,当你添加多个类构造函数,构造函数以不同的顺序,以不同的方式使用模板参数,或者根本不添加复杂性时,最多会非常混乱。
在这种情况下,我们经常使用&#34; make&#34;函数来补充类模板:
template <typename T1, typename T2>
A<T1, T2> make_A( const T1& t1, const T2& t2 )
{ return A<T1, T2>( t1, t2 ); }
int main()
{
double d = 5.2;
std::string s( "hi" );
auto a = make_A( d, s );
}
答案 1 :(得分:1)
它没有用,因为你没有指定参数化类型。你可能认为你做了,但你指定的只是构造函数参数,而不是模板参数。可以想象,struct A
的模板专用构造函数具有相同的构造函数参数但模板参数不同。
当然,编译器可能试图从参数中推断出类型并在没有警告的情况下进行编译,如果它找到一个唯一的匹配,但是这不会是一个滴答作响的定时炸弹等待爆炸你制作这个构造函数的瞬间:{ {1}}?
事实上,我认为提出A< int, string >::A ( double, string )
功能的其他回复也是在寻找麻烦。某处隐藏了你的代码,你可能会有一个make_A()
,在远离下游的地方爆炸。如果您不想输入,为什么不使用make_A(5,"whatever")
或typedef
?我总是发现using
需要更多的努力来阅读。
答案 2 :(得分:-1)
似乎任何类型A的对象都应该有两个参数,即double和std :: string。
不编译的代码行不使用这些参数。