ostream 和运算符 std::basic_string<char, std::char_traits<char>, std::分配器<char>>?

ostream and operator std::basic_string<char, std::char_traits<char>, std::allocator<char>>?

本文关键字:char gt std lt 运算符 分配器 traits basic ostream string      更新时间:2023-10-16

从答案中,我了解到std::string只是std::basic_string<char, std::char_traits<char>, std::allocator<char>>的typedef,模板参数替换不考虑用户定义的转换,因此编译器无法从矩形类型推断出CharT,Traits或分配器的类型,因此此重载不参与重载解析。

现在我用 std::basic_string, std::分配器> 代替 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);

现在我用 std::basic_string, std::分配器> 代替 std::string:
它仍然失败。为什么?

你误解了最初的问题。这不是因为你用std::string而不是直接std::basic_string<char, std::char_traits<char>, std::allocator<char>>。typedef 只是现有类型的另一个名称。您的两个转换运算符完全相同。您可以验证通过尝试将它们都放在类定义中是否会导致重定义错误。

在解析operator<<的重载时,两者都不会被考虑在内,因为转换不应用于模板函数排序。

重载解析首先找到一组可能调用的函数。在此阶段中,执行模板推导以查看模板是否是可能的候选模板。

然后,如果找到多个函数,则在尝试查找候选项中最接近的匹配项时考虑转换函数。

在您的情况下,从不考虑采用std::string运算符,因为编译器无法从Rectangle推断出CharT等。


一种解决方案是跳过转换运算符,而是为Rectangle添加一个operator<<。在里面你可以打电话给os << to_string(...等。