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<<重载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,Traits或Allocator从类型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)