运算符 double() 的使用不明确
Unclear use of operator double()
我有一个 Rectangle
class 转换运算符到 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;
}
我不明白为什么调用operator double()
,而不是operator std::string()
。
据我所知,根据C++ wikibook,
operator double
用于将 Rectangle
对象转换为 double
.
这是怎么回事?它与 int
传递给构造函数的事实有关吗?如果是,为什么?
您没有将矩形输出到流的运算符。 cout
确实有一个需要 double
的重载,并且您的 class 可以隐式转换为 double
以便选择它。
未选择字符串重载且未将其视为歧义的原因是因为字符串的 operator <<
是一个成员函数,不包含在 member overload and non member overload set of cout
. If we comment out the operator double
we can see we get a compiler error.[=20= 中]
如果我们想要调用 operator string
那么我们需要显式地将 r
转换为字符串。 Live Example
由于您没有为 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
推导出类型 CharT
、Traits
或 Allocator
],所以这个重载不参与重载决议。 (回想一下 std::string
只是 std::basic_string<char, std::char_traits<char>, std::allocator<char>>
的类型定义。)
因此有一个 operator<<
的重载比其他任何一个都更匹配,那就是 double
重载。不是模板,而是 class 模板的成员函数。
basic_ostream<CharT, Traits>& basic_ostream<CharT, Traits>::operator<<(double);
与其他原始类型重载相比,双重重载没有什么特别之处。在这种情况下,它是唯一可用的原始重载。
编译器对 int、char 等的行为相同。
请注意,如果我们有多个原始类型重载,编译器将抛出
error: ambiguous overload for 'operator<<' ...
我有一个 Rectangle
class 转换运算符到 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;
}
我不明白为什么调用operator double()
,而不是operator std::string()
。
据我所知,根据C++ wikibook,
operator double
用于将 Rectangle
对象转换为 double
.
这是怎么回事?它与 int
传递给构造函数的事实有关吗?如果是,为什么?
您没有将矩形输出到流的运算符。 cout
确实有一个需要 double
的重载,并且您的 class 可以隐式转换为 double
以便选择它。
未选择字符串重载且未将其视为歧义的原因是因为字符串的 operator <<
是一个成员函数,不包含在 member overload and non member overload set of cout
. If we comment out the operator double
we can see we get a compiler error.[=20= 中]
如果我们想要调用 operator string
那么我们需要显式地将 r
转换为字符串。 Live Example
由于您没有为 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
推导出类型 CharT
、Traits
或 Allocator
],所以这个重载不参与重载决议。 (回想一下 std::string
只是 std::basic_string<char, std::char_traits<char>, std::allocator<char>>
的类型定义。)
因此有一个 operator<<
的重载比其他任何一个都更匹配,那就是 double
重载。不是模板,而是 class 模板的成员函数。
basic_ostream<CharT, Traits>& basic_ostream<CharT, Traits>::operator<<(double);
与其他原始类型重载相比,双重重载没有什么特别之处。在这种情况下,它是唯一可用的原始重载。 编译器对 int、char 等的行为相同。
请注意,如果我们有多个原始类型重载,编译器将抛出
error: ambiguous overload for 'operator<<' ...