c – 为什么这个对成员函数的调用是模糊的?

前端之家收集整理的这篇文章主要介绍了c – 为什么这个对成员函数的调用是模糊的?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑这个类:
class Base{
public:
    void func(double a) = delete;
    void func(int a) const {}
};

int main(){
    Base base;

    base.func(1);
    return 0;
}

当使用clang编译时,会产生以下错误

clang++ --std=c++11 test.cpp 
test.cpp:22:7: error: call to member function 'func' is ambiguous
    base.func(1);

用g,会产生警告:

g++ -std=c++11 test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:22:13: warning: ISO C++ says that these are ambiguous,even though the worst conversion for the first is better than the worst conversion for the second: base.func(1);

为什么这个代码不明确?

解决方法

非静态成员函数,如下:
void func(double);    // #1
void func(int) const; // #2

也接受一个implicit object parameter,被认为是超负荷决议([over.match]/p1)任何其他争论:

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的非常量值)到Base&具有完全匹配等级(直接引用绑定产生一个Identity conversion) – 参见Table 13.从base到const Base&也是一个完全匹配的排名,但是,[over.ics.rank]/p3.2.6声明#1有一个更好的转换顺序:

— S1 and S2 are reference bindings (07005),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:

06003

现在对于第二个参数,从积分pr值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),[…]

这里,ICS0(#1)优于ICS0(#2),反之,ICS1(#2)优于ICS1(#1),所以编译器不能在两次重载之间进行选择并检测模糊.

猜你在找的C&C++相关文章