不明确使用operator double()

Ale*_*oft 15 c++ operator-overloading implicit-conversion

我有一个Rectangle类转换运算符,double并且std::string:

class Rectangle
{
public:
    Rectangle(double x, double y) : _x(x), _y(y) {}
    operator std::string ();
    operator double ();
private:
    double _x, _y;
    double getArea() {return _x * _y;}
};

int main()
{
    Rectangle r(3, 2.5);
    cout << r << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么operator double()被调用,而不是operator std::string().据我所知,根据C++ wikibook, operator double用于将Rectangle对象转换为double.

那么这里发生了什么?是否与int传递给构造函数的事实有关?如果是这样,为什么?

Nat*_*ica 12

您没有操作员将矩形输出到流. cout确实有一个带有a的重载,double你的类可以隐式转换为a,double这样就可以选择了.

没有选择字符串重载并且不被认为是歧义的原因是因为operator <<字符串是成员函数而不包含在成员重载非成员重载集中cout.如果我们注释掉,operator double我们就会发现编译错误.

如果我们想要operator string调用那么我们需要显式地r转换为字符串. Live Example

  • 很好的抓住.如果有人想解释为什么在不代表数字的类型上实现`operator double()`是一种不好的做法,他很难找到更好的例证:-) (6认同)
  • 那为什么不选择`string`转换呢? (3认同)

Okt*_*ist 7

由于您没有提供operator<<重载Rectangle,编译器会考虑其他参数可以转换为参数类型的重载.

如果任何重载是模板,则在重载解析之前会发生模板参数替换.编译器尝试从提供给函数的参数类型中推导出模板参数.

string超载不考虑,因为的模板参数替换失败:

template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os,
               const std::basic_string<CharT, Traits, Allocator>& str);
Run Code Online (Sandbox Code Playgroud)

模板参数替换不考虑用户定义的转换,因此编译器不能推断类型CharT,TraitsAllocator从类型Rectangle,所以这种过载不参与重载决议.(回想一下,这std::string只是一个typedef std::basic_string<char, std::char_traits<char>, std::allocator<char>>.)

因此,有一个重载operator<<比任何其他更好,这就是double过载.不是模板,而是类模板的成员函数.

basic_ostream<CharT, Traits>& basic_ostream<CharT, Traits>::operator<<(double);
Run Code Online (Sandbox Code Playgroud)