为什么对成员函数的调用不明确? [英] Why is this call to member function ambiguous?

查看:411
本文介绍了为什么对成员函数的调用不明确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑此类:

class Base{
public:
    void func(double a) = delete;
    void func(int a) const {}
};

int main(){
    Base base;

    base.func(1);
    return 0;
}

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

When compiled using clang++, it produces the following error:

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

使用g ++会产生警告:

With g++, a warning is produced:

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);

为什么此代码不明确?

Why is this code ambiguous ?

推荐答案

非静态成员函数,例如两个:

Non-static member functions, like the two:

void func(double);    // #1
void func(int) const; // #2

还接受隐式对象参数,该参数在重载中被考虑分辨率( [over.match]/p1 )作为任何其他参数:

accept also an implicit object parameter which is considered in overload resolution ([over.match]/p1) as any other argument:

重载解析是一种机制,用于在给定要作为调用参数的表达式列表以及可以基于调用上下文调用的一组候选函数的情况下,选择最佳函数来进行调用.最佳函数的选择标准是参数数量,参数与候选函数的参数类型列表的匹配程度,对象与隐式对象参数匹配的程度(对于非静态成员函数),以及候选函数的某些其他属性.

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.

将隐式对象参数合并到成员函数签名中后,编译器会看到两个重载:

After incorporating the implicit object parameter into the member functions signatures, the compiler sees two overloads:

void func(Base&, double);    // #1
void func(const Base&, int); // #2

并尝试根据调用选择最佳可行的功能:

and tries to select the best viable function based on the call:

Base base;
base.func(1);

base(类型为Base的非常量左值)到Base&的转换具有完全匹配等级(直接引用绑定会产生

The conversion from base (which is a non-const lvalue of type Base) to Base& has an Exact Match rank (direct reference binding yields an Identity conversion) -- see Table 13. The conversion from base to const Base& is also of an Exact Match rank, however, [over.ics.rank]/p3.2.6 declares #1 to have a better conversion sequence:

-S1和S2是引用绑定( [dcl.init.ref] ),并且引用所引用的类型除顶级cv限定符外为相同类型,并且由S2初始化的引用所引用的类型比由初始化的引用所引用的类型更具cv资格. S1是指. [示例:

— 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 1double的转换是 Floating-integral转换( [over.ics.rank]/p3.2.2 ):

Now for the second parameter, a conversion from an integral prvalue 1 to double is a Floating-integral conversion ([conv.fpint]) which is given a Conversion rank. On the other hand, 1 to int is an Identity conversion which is of an Exact Match rank. For this argument, #2 is considered to have a better conversion sequence ([over.ics.rank]/p3.2.2):

-S1的等级优于S2的等级,或者S1和S2具有相同的等级,并且可以通过以下段落中的规则加以区分,或者如果不是,则为[...]

— 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, [...]

要成功完成重载解析,需要存在一个转换顺序不同的参数(

Overload resolution to succeed requires that there exists at most one parameter for which conversion sequences differ ([over.match.best]):

基于这些定义,如果对于所有自变量i,ICS i (F1)的转换顺序都不比ICS <更差,则将可行的函数F1定义为比另一个可行的函数F2更好的函数. sub> i (F2),然后

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

-对于某些参数j,ICS j (F1)比ICS j (F2)更好,或者,如果不是,则... ]

— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that, [...]

在这里,ICS 0 (#1)比ICS 0 (#2)好,但是ICS 1 (# 2)比ICS 1 (#1)更好,因此编译器无法在两个重载之间进行选择并检测到歧义.

Here, ICS0(#1) is better than ICS0(#2), but in turn, ICS1(#2) is better than ICS1(#1), so the compiler can't choose between the two overloads and detects ambiguity.

这篇关于为什么对成员函数的调用不明确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆