c ++模板化构造函数错误

时间:2013-06-28 17:00:36

标签: c++ templates reference template-deduction

更多模板化的困境......我喜欢C ++,但有时我讨厌它。

我无法弄清楚为什么编译器在这里抱怨,以及我能做些什么呢。

struct blah
{
   template<class t>
   blah(void(*)(t), t){}
};

void Func(int i) {}
void Func2(int& i) {}

void test()
{
   int i = 3;
   blah b(Func, i);   
   blah b2(Func2, i);        //error C2660: 'blah::blah' : function does not take 2 arguments
   blah b3(Func2, (int&)i);  //error C2660: 'blah::blah' : function does not take 2 arguments

}

这里发生了什么?

我正在使用MSVC2008。

3 个答案:

答案 0 :(得分:7)

其他答案解释了发生了什么:当模板参数推导找到两种推断模板参数的方法时,它会单独查看每个参数,并且它们都必须完全一致。

您可以通过确保t的第二次使用处于“非推断的上下文”中来使本课程以您的预期方式运行:

template<typename T>
struct identity { typedef T type; };

struct blah
{
   template<class t>
   blah(void(*)(t), typename identity<t>::type){}
};

这样,当调用blah构造函数时,C ++将从函数指针中推导出t,但不会尝试从第二个参数中推导出它。推导出的类型然后在两个地方被替换。

答案 1 :(得分:3)

如果您编译相同的snippet on gcc,则会收到更直观的错误消息:

test.cpp:14:20: note:   deduced conflicting types for parameter ‘t’ (‘int&’ and ‘int’)

编译器推断第一个参数的模板参数tint&,第二个参数为int。由于这些是不同的类型,因此会出现编译错误。

答案 2 :(得分:3)

在MSVC 2012中,Intellisense说(大致翻译):

  

1智能感知:没有构造函数的实例“”blah :: blah“”匹配参数列表。

     

参数类型为:(void (int &i), int)

@mfontanini是正确的,你在这里有一个演绎问题。

您可以添加第二个构造函数

template<class t>
blah(void(*)(t), t){}
template<class t>
blah(void(*)(t&), t&){}