C ++模板和对重载函数的歧义调用

婆罗门

我陷入了以下问题。我使用的是Xcode 7,但我的项目没有任何问题。尝试在Visual Studio Express 2015上对其进行编译后,我"Error C2668 ambiguous call to overloaded function"在代码中得到了消息我找不到与该问题有关的特定于Visual Studio的东西。

我做了一个应该在VS上使用的最小工作示例(Xcode上没有错误)。怪异的部分涉及该func2部分。好像VS编译器无法自动推断出比限制更多的类型和/或参数。

更新 :

Sam Varshavchik提出了一种解决方法,其中包括将部分专业化与中间模板类一起使用。这是我要避免的解决方案。首先是因为它在上下文中不方便应用在我的代码中,其次是因为这个编译错误对我来说尚不清楚。Xcode7中不会显示此错误,即使在VS中func2也没有错误。尽管我同意WhiZTiM的解释,但事实是,在这种情况下,重载有时可以起作用,有时则不能。我真的很想知道为什么。

更新2:

根据bogdan的说法,这可能是GCC和MSVC中的错误。我将尝试举报。(我非常喜欢Visual Studio,这是我的第一周)

更新3:

错误报告于https://connect.microsoft.com/VisualStudio/feedback/details/3076577

functions.h:

template <class T>
class BX {
public :
    BX() {}
    ~BX() {}
};

template <class T1, class T2>
class G {
public :
    G() {}
    ~G() {}
};

template <template <class T> class T1, class T>
class DT {};

class B {
public :
    //I want func to work
    template <template <class T> class T1, class T, class M>
    static void func(const M& m, const DT<T1, T>* dt, T1<T>& val) {}

    template <template <class T> class T1, class T, class M>
    static void func(const G<T1<T>, M>& g, const DT<T1, T>* dt, T1<T>& val) {}

    //here is a small variation of func as a test
    template <template <class T> class T1, class T, class M>
    static void func2(const M& m, const DT<T1, T>* dt) {}

    template <template <class T> class T1, class T, class M>
    static void func2(const G<T1<T>, M>& g, const DT<T1, T>* dt) {}
};

main.cpp

int main() {
    BX< int > bx;
    G<BX< int >, int> g;
    DT<BX, int>* dt;
    B::func(g, dt, bx);//Error  C2668   'B::func': ambiguous call to overloaded function
    B::func2(g, dt);//no error
}
博格丹

这看起来像MSVC和GCC中的错误。该调用应解决第二个过载(Clang和EDG正在这样做)。

对于call B::func(g, dt, bx),名称查找将找到两个func模板。对模板参数进行推导和替换,以生成函数模板特化声明,这些声明随后可参与重载解析。两种模板的推论都成功,我们还剩下两个专长:

void B::func<BX, int, G<BX<int>, int>>(const G<BX<int>, int>&, const DT<BX, int>*, BX<int>&);
void B::func<BX, int, int>            (const G<BX<int>, int>&, const DT<BX, int>*, BX<int>&);

这两个函数具有相同的参数声明子句,因此显然,重载解析无法基于调用参数的转换来区分它们。它必须求助于该过程的最后两个步骤。

首先,如果其中一个功能是模板专业化,而另一个功能不是模板专业化,则首选非模板功能。在这里不适用。

最后,它查看了合成两个专业化声明的模板。如果根据功能模板的部分排序,其中一个模板比另一个模板更专业,则首选相应的专业化。(这是过程中唯一恢复原始模板的位置。)

下面的描述不是很准确,并且跳过了很多细节,但是我尝试着重于与这种情况相关的部分。非常粗略:

  • 首先,从两个模板的函数参数声明中删除引用和cv限定词,得到:

    F1(M          , const DT<T1, T>*, T1<T>)
    F2(G<T2<U>, V>, const DT<T2, U>*, T2<U>)
    

    (模板参数名称已更改以避免混淆)

  • 然后,尝试进行推论,就好像是使用另一个模板的函数参数的形式作为参数调用一个模板,然后尝试使用另一种方法进行推导一样。在这种情况下,最后两对对应的参数具有相同的形式,因此推论在两种方法中都成功。对于第一对相应参数:

    • 推导M从形式的论点G<T2<U>, V>作品; M推导为G<T2<U>, V>
    • 推导T2UVG<T2<U>, V>从形式的参数M不工作(M可以是任何东西)。

    换句话说,G<T2<U>, V>是一种比“更具体”的形式M它不能代表所有M可以代表的类型这是更专业的人员试图在这种情况下进行形式化的直观含义

  • 因此,推导适用于从F2到的所有对对应参数F1,但反之则不行。这使得F2更多的专业比F1在偏序的条款。

这意味着在过载解析中,首选与第二个模板相对应的专业化。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++模板和对重载函数的歧义调用

来自分类Dev

模板编程:对重载函数的歧义调用

来自分类Dev

C ++ 11 auto,std :: function和对重载函数的模糊调用

来自分类Dev

对重载整数构造函数的歧义调用

来自分类Dev

调用重载的构造函数会产生歧义错误C ++

来自分类Dev

可变参数模板函数中对重载函数的歧义调用

来自分类Dev

VS2013中使用可变参数模板时“对重载函数的歧义调用”

来自分类Dev

在VS2013中使用可变参数模板时“对重载函数的歧义调用”

来自分类Dev

C#函数对重载方法的引用

来自分类Dev

错误C2668:'boost :: bind':对重载函数的模棱两可的调用

来自分类Dev

如何解决“ fpclassify”:对重载函数的歧义调用

来自分类Dev

C ++模板函数的重载

来自分类Dev

模板函数重载C ++

来自分类Dev

C ++与Java中函数重载的歧义

来自分类Dev

C ++重载函数和函数模板-不同的行为?

来自分类Dev

C ++重载函数和函数模板-不同的行为?

来自分类Dev

MSVC-C2668对重载函数的模棱两可的调用-它是编译器错误吗?

来自分类Dev

C ++:可变参数模板和函数重载

来自分类Dev

C ++中的模板专业化和函数重载

来自分类Dev

C ++模板和模糊函数调用

来自分类Dev

C ++模板和模糊函数调用

来自分类Dev

C ++模板函数重载解析

来自分类Dev

C ++中的模板函数重载

来自分类Dev

'sqrt':对重载函数.. \ assimp \ vector3.inl的歧义调用

来自分类Dev

当我添加头文件“ boost / function”时,使用“ bind”对重载函数进行歧义调用

来自分类Dev

儿童类C ++中的歧义函数调用

来自分类Dev

递归调用重载的C ++函数

来自分类Dev

C ++重载函数作为模板参数

来自分类Dev

C ++模板函数重载解析错误

Related 相关文章

热门标签

归档