来自the answer,我了解到std::string
只是std::basic_string<char, std::char_traits<char>, std::allocator<char>>
的typedef,模板参数替换不考虑用户定义的转换,因此编译器无法推断出类型CharT,Traits ,或类型为Rectangle的Allocator,因此此重载不参与重载解析。
现在我替换std :: basic_string,std :: allocator&gt;对于std :: string:
class Rectangle
{
public:
Rectangle(double x, double y) : _x(x), _y(y) {}
operator std::basic_string<char, std::char_traits<char>, std::allocator<char>> () {
return std::basic_string<char, std::char_traits<char>, std::allocator<char>>(to_string(_x) + " " + to_string(_y));
}
//operator double() {
// return _x;
//}
private:
double _x, _y;
double getArea() { return _x * _y; }
};
int main()
{
Rectangle r(3, 2.5);
cout << r << endl;
return 0;
}
它仍然失败。为什么?
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);
答案 0 :(得分:3)
现在我替换std :: basic_string,std :: allocator&gt;对于std :: string:
它仍然失败。为什么呢?
你误解了原来的问题。这不是因为您使用std::string
而不是直接std::basic_string<char, std::char_traits<char>, std::allocator<char>>
。 typedef只是现有类型的另一个名称。您的两个转换运算符完全相同。您可以通过尝试将它们放在类定义中来验证它,这将导致重新定义错误。
解决operator<<
的重载时不会考虑这两个问题,因为转换不会应用于模板函数排序。
答案 1 :(得分:2)
Overload resolution first 找到一组可能要调用的函数。在此阶段,执行模板推导以查看模板是否可能是候选者。
然后,如果找到多个函数,则在尝试查找候选者中最接近的匹配时会考虑转换函数。
在您的情况下,从不考虑使用std::string
的运算符,因为编译器无法从CharT
推导出Rectangle
等。
解决方案是跳过转化运算符,而是为operator<<
添加Rectangle
。在里面你可以打电话给os << to_string(...
等。