About
RSS

Bit Focus


C++ 到底怎么使用流来输出对象

    书上写的做法当然是类似
struct my_type {
    void set_x(int xx);
    void set_y(double yy);

    my_type(int xx, double yy)
        : x(xx)
        , y(yy)
    {}

    friend std::ostream& operator<<(std::ostream& os, my_type const&);
private:
    int x;
    double y;
};

std::ostream& operator<<(std::ostream& os, my_type const& m)
{
    return os << m.x << ' ' << m.y;
}
    一般使用这样没问题, 不过在想要写得很省略的用况下, 这样就很纠结
my_type m(10, 20.0);
std::stringstream ss;
std::string image = (ss << m).str(); // WRONG!
因为 operator<< 返回的类型已经变成没有 str() 取得字符串函数的基类 std::ostream& 了. 看起来要什么流类型进来什么流类型出才行, 比如
struct my_type {
    void set_x(int xx);
    void set_y(double yy);

    my_type(int xx, double yy)
        : x(xx)
        , y(yy)
    {}

    friend template<typename _OS>
    _OS& operator<<(_OS& os, my_type const&); // WRONG
private:
    int x;
    double y;
};

template <typename _OS>
_OS& operator<<(_OS& os, my_type const& m)
{
    os << m.x << ' ' << m.y;
    return os;
}
不过很遗憾, 泛型函数无法做朋友
    那要不先把 my_type 对象弄成字符串了, 再把字符串输出好了
struct my_type {
    void set_x(int xx);
    void set_y(double yy);

    my_type(int xx, double yy)
        : x(xx)
        , y(yy)
    {}

    std::string str() const
    {
        std::stringstream ss;
        ss << m.x << ' ' << m.y;
        return ss.str();
    }
private:
    int x;
    double y;
};

template <typename _OS>
_OS& operator<<(_OS& os, my_type const& m) // ACTUALLY NOT NEEDED ANY MORE
{
    os << m.str();
    return os;
}
这看起来多疼啊.

    一个可能的方案是, 为每个自定义类型实现 str() 成员函数 (有必要的还可以虚一下), 然后全局声明一个
template <typename _OS, typename _T>
_OS& operator<<(_OS& os, _T const& t)
{
    os << t.str();
    return os;
}
也许这样会好很多.

Permanent Link: ?p=177 Load full text

Post tags:

 C++
 Operator Overload
 Output Stream


. Back to Bit Focus
NijiPress - Copyright (C) Neuron Teckid @ Bit Focus
About this site