【问题标题】:c++ templated constructor errorc++模板化构造函数错误
【发布时间】:2013-06-28 17:00:36
【问题描述】:

更多的模板问题...我喜欢 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。

【问题讨论】:

  • (int&amp;)ii 相同(两者都没有引用类型)

标签: c++ templates reference template-argument-deduction


【解决方案1】:

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

通过确保 t 的第二次使用是在“非推断上下文”中,您可能可以让这个类按照您的预期工作:

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

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

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

【讨论】:

    【解决方案2】:

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

    1 IntelliSense:没有构造函数“blah::blah”的实例与参数列表匹配。

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

    @mfontanini 是正确的,你这里有一个推论问题。

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

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

    【讨论】:

    • 不幸的是,这不是我的选择。我正在研究一个回调包装器,它可以采用带有任意参数的任意函数,并且我不想处理可能的引用参数的组合爆炸。我想我将不得不使用静态“make”函数而不是构造函数。
    【解决方案3】:

    如果你编译相同的snippet on gcc,你会得到更直观的错误信息:

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

    编译器推断模板参数t对于第一个参数是int&amp;,对于第二个参数是int。由于这些是不同的类型,因此您会收到编译错误。

    【讨论】:

    • 但即使我明确地投射它也无济于事(示例已编辑)
    • "因此,甚至 (...)" -1 没有int&amp; 类型的表达式,句号。没有任何内容被删除。
    • @curiousguy 所以你是说(int&amp;)i 不是int&amp; 类型?
    • @curiousguy 当然演员什么都不做。我还是不明白你的意思。你能解释一下this吗?
    • @curiousguy 是的,演员什么都不做。我是说演员修改了什么吗? OP使用了强制转换,这就是为什么我提到强制转换不会改变模板参数推导,它完全一样。所以我们知道(int&amp;)x(x) 的类型是int&amp;,对吧?那么“没有int&amp;类型的表达式是什么意思?
    猜你喜欢
    • 2016-12-04
    • 2011-05-24
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多