C++ 运算符 == 和隐式转换解析

Oli*_*ree 4 c++ operator-overloading overload-resolution implicit-conversion

如果我有一个struct A定义为:

struct A {
    const char *data;
    operator const char * () const { return data; }
    friend bool operator== (const A &s1, const char *s2)
    { return /* typical string comparison result */; }
};
Run Code Online (Sandbox Code Playgroud)

而我写的A{"hello"} == "test2"A::operator==叫什么?标准中的内容是什么(为什么不A隐式转换为const char *?)

怎么样"test2" == A{"hello"}A在这种情况下是否已转换?

编辑:如果struct A也有成员呢:

friend bool operator== (const char *s1, const A &s2)
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 5

当你做

A{"hello"} == "test2"
Run Code Online (Sandbox Code Playgroud)

我们对 执行重载决议operator==。首先,我们通过名称查找找到可行的候选者([over.match.viable]):

operator==(A const&, const char*);    // yours
operator==(const char*, const char*); // built-in
Run Code Online (Sandbox Code Playgroud)

接下来,我们确定哪个候选者具有最佳的隐式转换序列。这是 [over.match.best] 中的第一个决胜局:

鉴于这些定义,如果对于所有参数i,ICS i (F1) 不是比 ICS i (F2)更差的转换序列,然后 (1.3) — 对于某些参数,则将可行函数F1定义为比另一个可行函数更好的函数参数j,ICS j (F1) 是比 ICS j (F2)更好的转换序列,或者,如果不是,则 [...]F2

两个运算符都是第二个参数的完全匹配。在第一个参数上,您operator==是精确匹配,而内置函数需要用户定义的转换。Exact Match 是最好的转换类型,而用户定义的则是最差的——因此,您的转换顺序更好,成为最好的可行功能。

从更广泛的意义上讲, theA不会隐式转换为 a ,const char*因为有一个更好的选择,它不必是。


当你这样做时:

"test2" == A{"hello"};
Run Code Online (Sandbox Code Playgroud)

您的候选对象不可行 - 没有从const char*to A const&(第一个参数)的隐式转换,因此唯一可行的候选对象是 for 的内置比较const char*,它需要用户定义的从Ato转换const char*

如果您希望A::operator==调用您的对象,则必须为operator==(const char*, A const&).

  • @GillBates [\[over.ics.rank\]](http://eel.is/c++draft/over.ics.rank),不过你也想看看 [\[over.best. ics\]](http://eel.is/c++draft/over.best.ics)。 (2认同)