非静态成员函数,像两:
void func(double); // #1
void func(int) const; // #2
也接受其在过载分辨率([over.match]/p1)的任何其他参数视为implicit object parameter:
Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of candidate functions that can be called based on the context of the call. The selection criteria for the best function are the number of arguments, how well the arguments match the parameter-type-list of the candidate function, how well (for non-static member functions) the object matches the implicit object parameter, and certain other properties of the candidate function.
结合隐式后对象参数放入成员函数签名中,编译器会看到两个过载:
void func(Base&, double); // #1
void func(const Base&, int); // #2
,并尝试选择基于所述呼叫的最佳可行函数:
Base base;
base.func(1);
从base
的转化率(其为Base
类型的非const左值),以Base&
具有精确匹配秩(直接参考结合产生Identity conversion) - 见Table 13。从base
到const Base&
的转化也是精确匹配排名,然而,[over.ics.rank]/p3.2.6声明#1
有一个更好的转换序列:
— S1 and S2 are reference bindings ([dcl.init.ref]), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers. [ Example:
int f(const int &);
int f(int &);
int g(const int &);
int g(int);
int i;
int j = f(i); // calls f(int &)
int k = g(i); // ambiguous
现在对于第二个参数,从整体prvalue 1
到double
转换是一个浮动积分转换([conv.fpint])它给出了一个转换排名。另一方面,1
到int
是身份转换这是一个完全匹配排名。对于这样的说法,#2
被认为具有更好的转换序列([over.ics.rank]/p3.2.2):
— the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below, or, if not that, [...]
重载分辨率成功要求存在至多一个参数用于其转换序列不同([over.match.best]):
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that, [...]
这里,ICS (#1)是比ICS更好(#2),但反过来,ICS (#2)是比ICS更好(#1),因此编译器无法在两次重载之间进行选择并检测出模糊性。
整数可以很容易地转换为浮点类型。虽然'func(int)'是最好的匹配,'func(double)'仍然是一个可行的选择,使得这个调用不明确。 –
您似乎遇到了一些涉及const和非const成员函数的棘手逻辑。 FWIW,将'func(double)'改为'const'成员函数可以消除这个问题。 –