【问题标题】:C++ operator == and implicit conversion resolutionC++ 运算符 == 和隐式转换解析
【发布时间】:2016-07-13 15:35:48
【问题描述】:

如果我将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 */; }
};

我写A{"hello"} == "test2",是A::operator== 调用吗?标准中的内容是什么(为什么A 没有隐式转换为const char *?)

"test2" == A{"hello"} 呢?在这种情况下A 是否转换?

编辑:如果struct A 也有成员怎么办:

friend bool operator== (const char *s1, const A &s2)

【问题讨论】:

  • 只使用 std::string
  • @Davidbrcz 这个问题根本不是这个问题。
  • 我认为friend 使函数-成员(即全局)。
  • 我编辑了标题,将“隐式转换”更改为“隐式转换”。没有隐式强制转换之类的东西。强制转换是显式转换运算符。
  • @Gill Bates,是的。使用std::string 将使他的原始请求无效,因为即使从A->std::string 转换中选择operator==std::strings,它也会完美地工作。在这里,对称性被打破,这是令人讨厌的错误来源,尤其是因为 2 个字符串文字可能具有或可能不具有相同的地址。它完全留给实现......经典的XY问题!

标签: c++ operator-overloading implicit-conversion overload-resolution


【解决方案1】:

当你这样做时

A{"hello"} == "test2"

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

operator==(A const&, const char*);    // yours
operator==(const char*, const char*); // built-in

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

鉴于这些定义,如果对于所有参数 i,ICSi(F1) 的转换序列并不比 ICSi(F2) 差,然后
(1.3) — 对于某些参数 j,ICSj(F1) 是比 ICSj(F2) 更好的转换序列,或者,如果不是那样,[...]

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

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


当你这样做时:

"test2" == A{"hello"};

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

如果您希望调用 A::operator==,则必须为 operator==(const char*, A const&) 添加新的重载。

【讨论】:

  • 我认为 OP 是在标准中的相关部分之后决定了它在这里发生的原因和原因。
  • 要明确一点:在第二种情况下,如果我有A::A(const char *s) {},那么实际上会调用A("test") == A{"hello"}?还是需要隐式转换?
  • @GillBates 是的,我是,所以我可以知道我刚才没有想到的所有其他情况。我想他们会在同一套规则中。也许我应该澄清问题?
  • @GillBates 当然,虽然标准中有很多相关部分。
  • @GillBates [over.ics.rank],不过你也想看看[over.best.ics]
猜你喜欢
  • 2010-10-27
  • 2013-08-25
  • 2010-12-09
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多