【问题标题】:C++ overload resolution, conversion operators and constC++ 重载决议、转换运算符和 const
【发布时间】:2015-03-29 05:48:49
【问题描述】:

在这种情况下

void f(int *);
void f(const int *);
...
int i;
f(&i);

情况很清楚 - f(int *) 被调用,这似乎是正确的。

但是,如果我有这个(它是错误地这样做的(*)):

class aa
{
public:
    operator bool() const;
    operator char *();
};

void func(bool);

aa a;
func(a);

operator char *() 被调用。我无法弄清楚为什么这样的决策路径会比使用运算符 bool() 更好。有什么想法吗?

(*) 如果将 const 添加到第二个运算符,代码当然可以按预期工作。

【问题讨论】:

  • std::string 的设计者有充分的理由让c_str() 成为命名成员函数而不是转换运算符。
  • 因为operator char*();是一个非const的成员函数。
  • operator bool() { return const_cast<aa const&>(*this); } 也修复了它。
  • 不,抱歉,这将是一个糟糕的解决方案。

标签: c++ overloading language-lawyer conversion-operator const-method


【解决方案1】:

因为对于使用转换运算符的用户定义转换,返回类型到目标类型的转换(即char*bool)在对象参数转换之后被考虑,即将对象参数a 转换为隐式对象参数。 [over.match.best]/1:

鉴于这些定义,一个可行的函数F1 被定义为 如果所有参数都比另一个可行的函数F2 更好的函数 i, ICSi(F1) 并不是比 ICSi(F2) 更差的转化序列,然后

  • 对于某些论点jICSj(@ 987654328@) 是比 ICSj(F2 更好的转换序列)或者,如果不是这样

  • 上下文是通过用户定义的转换进行的初始化(参见 8.5、13.3.1.5 和 13.3.1.6)和 从F1 的返回类型到目标类型(即 实体被初始化)是比标准转换序列更好的转换序列 F2 的返回类型到目标类型

所以因为隐含的对象参数,它是一个引用,不是const-operator char* 的引用,所以根据第一个要点,它是一个更好的匹配。

【讨论】:

  • @LightnessRacesinOrbit [over.match.funcs]/4.
  • 我不知道为什么会这样说,但是用代码试试,你会看到的。
  • auto f = std::bind(&A::f, std::ref(a)); 嗯,TIL。我总是传递一个指针。
  • @LightnessRacesinOrbit 我想你错过了this 和隐式对象参数/参数之间的区别。后者仅出于重载解决目的而存在。
  • 我一定是在依赖 bind 便利超载。
【解决方案2】:

aaa 的非常量实例,因此非常量转换运算符比常量转换运算符(需要添加常量)更好(精确)匹配,即使返回类型不匹配好吧。

【讨论】:

    【解决方案3】:

    您的“aa”对象不是 const,因此 C++ 更喜欢非常量转换。

    如果你将 "aa" 设为 const,那么将使用 const bool() 转换运算符。

    【讨论】:

    • 我自己也到了那里 :) ,但仍然不明白为什么这是一个好的设计选择。将 'this' 隐式转换为 const(以扩大合适的函数池)似乎比转换结果要小得多。
    • 重点是:声明为 const 的函数可能适合在非常量对象上使用。如果看起来确实如此,那么您的代码中的“const”要么太多,要么太少。
    • 从更愤世嫉俗的角度来看,constness 是在隐式 bool/char/int/float/etc 转换之后很久才发明的,那时语言设计者知道让他们的功能变得白痴很重要-证明。
    • “声明为 const 的函数可能不适合在非常量对象上使用。” 我可以在非常量 std::string 上调用 size()
    • 妈的,我把“非”放错地方了,现在编辑评论已经太晚了。
    猜你喜欢
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多