操作符double()的使用不明确

Unclear use of operator double()

本文关键字:不明确 double 操作符      更新时间:2023-10-16

我有一个Rectangle类,具有到doublestd::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;
}

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

这是怎么回事?它是否与传递给构造函数的int有关?如果是,为什么?

没有将矩形输出到流的操作符。cout确实有一个接受double的重载,你的类可以隐式地转换为double,这样就可以选择。

string重载没有被选中,也没有被认为是不义的,因为string的operator <<是成员函数,不包含在cout的成员重载和非成员重载集合中。如果我们注释掉operator double,我们可以看到我们得到一个编译器错误。

如果我们想要调用operator string,那么我们需要显式地将r强制转换为字符串。<<kbd>生活例子/kbd>

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

如果任何重载都是模板,则在重载解析之前对它们进行模板实参替换。编译器尝试从提供给函数的实参类型中推断出模板形参。

没有考虑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);

模板实参替换不考虑用户定义的转换,因此编译器不能从Rectangle类型推导出CharTTraitsAllocator类型,因此该重载不参与重载解析。(回想一下,std::string只是std::basic_string<char, std::char_traits<char>, std::allocator<char>>的一个类型定义。)

因此,operator<<的一个重载比其他任何重载都更匹配,那就是double重载。不是模板,而是类模板的成员函数。

basic_ostream<CharT, Traits>& basic_ostream<CharT, Traits>::operator<<(double);

与其他基本类型的重载相比,双重载没有什么特别之处。在这种情况下,它是唯一可用的原语重载。对于int、char等类型,编译器的行为是一样的。

注意,如果有多个基本类型重载,编译器会抛出

error: ambiguous overload for 'operator<<' ...