为什么在这个函数调用中没有歧义
Why no ambiguity in this function call?
我想知道为什么这个函数调用中没有歧义:
#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?
}
http://coliru.stacked-crooked.com/a/241ce5ab82b4a018
有一个隐式转换序列的排序,如[over.ics.rank]中所定义,emphasis mine:
当比较隐式转换序列的基本形式时
-标准转换序列(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]的"null成员指针转换",并且是标准转换序列。第二个将匹配省略号,并且是省略号转换序列。按[超过.ics.rank],前者优先。没有歧义,一个绝对比另一个好。
如果我们有两个等价的转换序列,而编译器无法在这两个序列之间做出决定,则会出现不明确的重载。考虑一下我们是否有这样的东西:
static char testFun(int* ) { return 0; }
static int testFun(char* ) { return 0; }
testFun(0);
现在,就转换序列而言,两个重载都是等效的,所以我们有两个可行的候选者。
您有一个标准转换与省略号转换。该标准规定,标准转换是比后者更好的转换序列。[over.ics.rank]/p2:
标准转换序列(13.3.3.1.1)是比用户定义的转换更好的转换序列序列或省略号转换序列
指向成员转换的指针是标准转换序列。0
是一个空指针常量,可以转换为指向成员的指针。[conv.mem]/p1:
空指针常量(4.10)可以转换为指向成员类型的指针;结果是null成员该类型的指针值,并且可以与任何指向非空指针创建的成员的指针区分开来常数这种转换称为空成员指针转换。
因此,第一过载是优选的。
13.3.2可行功能参数少于m的候选函数只有在其参数列表中有省略号时才可行(8.3.5)。为了解决过载问题,任何没有相应参数的参数都被视为"匹配省略号"(13.3.3.1.3)。
还有
可行功能给定如上所述构造的候选函数集,过载解决的下一步是检查自变量和参数,以将该集简化为可行函数集要包含在可行函数集中,候选函数必须满足以下条件:
1) 如果有M个参数,则恰好具有M个参数的候选函数是可行的
2) 如果候选函数的参数少于M个,但有省略号参数,则它是可行的
[…]
过载分辨率
空指针文字0应该与接受函数指针的函数完全匹配,并被视为比匹配任何内容都强(...
)。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- std::bind 是否实现了 std::ref 和 std::cref 来消除函数调用的歧义?
- C++ 类的构造函数和函数调用运算符 () 重载之间的歧义
- 函数调用歧义(用户定义的转换和 Derived2Base 指针转换)
- 函数调用带有指针、引用和常量引用参数的歧义
- 在隐式转换后的智能指针上删除函数调用中的歧义
- 为什么在这个函数调用中没有歧义
- 推导函数调用时出现歧义问题
- 如何消除GCC c++中函数调用的歧义
- 这是解决函数调用歧义的正确方法吗?
- c++中的函数调用歧义