C++ 为什么在这个函数调用中没有歧义?

C++ 为什么在这个函数调用中没有歧义?,c++,C++,我想知道为什么这个函数调用中没有歧义: #include <iostream> #include <vector> template <class T> class C { public: typedef char c; typedef double d; int fun() {} static c testFun( decltype(&C::fun) ) {return c();} static d t

我想知道为什么这个函数调用中没有歧义:

#include <iostream>
#include <vector>

template <class T>
class C
{
public:
    typedef char c;
    typedef double d;

    int fun() {}

    static c testFun( decltype(&C::fun) ) {return c();} 
    static d testFun(...) { return d(); }
};

int main() {
    C<int>::testFun(0); // Why no ambiguity?
}
#包括
#包括
模板
C类
{
公众:
typedef-charc;
双d型;
int fun(){}
静态c testFun(decltype(&c::fun)){return c();}
静态d testFun(…){return d();}
};
int main(){
C::testFun(0);//为什么没有歧义?
}

13.3.2可行功能 只有当参数列表中有省略号(8.3.5)时,参数少于m的候选函数才可行。为了解决重载问题,没有相应参数的任何参数都被视为“匹配省略号”(13.3.3.1.3)

而且

可行函数 给定如上所述构造的候选函数集,重载解析的下一步是检查参数和参数,以将该集缩减为可行函数集 要包含在可行函数集中,候选函数必须满足以下条件:
1) 如果有M个参数,则正好有M个参数的候选函数是可行的
2) 如果候选函数的参数少于M,但有省略号参数,则该函数是可行的。
[…]


有一个隐式转换序列的排序,如[over.ics.rank]中所定义,强调:

在比较隐式转换序列的基本形式时…
-标准转换序列(13.3.3.1.1)比用户定义的转换序列更好 序列或省略号转换序列,和
-用户定义的转换序列(13.3.3.1.2)比省略号转换更好 顺序(13.3.3.1.3)

所以我们有两个功能:

static char   testFun( int (C::*)() ) { return char(); }
static double testFun( ... ) { return double(); }
这两个函数都适用于
testFun(0)
。第一个涉及到[conv.mem]中的“空成员指针转换”,是一个标准转换序列。第二个匹配省略号,是省略号转换序列。根据[over.ics.rank],前者是首选。没有歧义,一个比另一个好

如果我们有两个编译器无法决定的等价转换序列,就会出现不明确的重载。考虑一下我们是否有类似的事情:

static char testFun(int* ) { return 0; }
static int testFun(char* ) { return 0; }

testFun(0);

现在两个重载在转换序列中都是等价的,所以我们有两个可行的候选

空指针文本0应该与接受函数指针的函数完全匹配,并被视为比任何匹配的函数都强(
)。

您有标准转换和省略号转换。该标准指出,标准转换是比后者更好的转换顺序。[over.ics.rank]/p2:

标准转换顺序(13.3.3.1.1)比用户定义的转换顺序更好 序列或省略号转换序列

指向成员转换的指针是标准转换序列
0
是一个空指针常量,可以转换为指向成员的指针。[conv.mem]/p1:

空指针常量(4.10)可以转换为指向成员类型的指针;结果是空成员 该类型的指针值,可与任何指向非空指针创建的成员的指针区分 常数这种转换称为空成员指针转换


因此,首选第一个重载。

这里的歧义对我来说没有意义<代码>是一个包罗万象的问题。具体类型应放在首位。这正是语言所做的。