继承自std :: ostringstream

时间:2014-05-18 21:07:01

标签: c++ templates stringstream

在我的项目中,我使用一个名为Message的类,它继承自std :: ostringstream,打印出其他类类型的人类可读信息。

所以它的<<运算符多次重载我自己的类类型,我打算打印出来。

class Message : public ostringstream
{
public:
    Message() {};
    virtual ~Message() {};

    Message& operator <<(const MyTypeA &a) { return *this << a.getStr(); };
    Message& operator <<(const MyTypeB &b) { return *this << b.identifier(); };
    Message& operator <<(const MyTypeC &c) { return *this << c.foo(); };

    // Pass everything unknown down to ostringstream, and always return a Message&
    template<class T>
    Message& operator <<(const T &t)
    {
        (std::ostringstream&)(*this) << t;
        return *this;
    }
};

没有模板

MyTypeA a,b;
Message m;
m << a << "-" << b;

代码将无法编译,因为(m&lt;&lt;&lt;&lt;&lt;&#;&#34; - &#34;)将返回ostringstream&amp;这将无法采取&#39;#39;。所以我使用模板确保始终返回Message&amp;。

我的问题:

Message m;
m << "Hello, world" << std::endl;

生成一个veeery long编译器错误,我不知道为什么。

Here是一个简约的&#34;不是&#34;我的问题的可编译示例,here是相应的编译器输出。

2 个答案:

答案 0 :(得分:8)

从任何流类派生以创建新流!从std::ostreamstd::istream派生的唯一原因是创建正确设置的流以使用合适的流缓冲区。您应该从std::streambuf派生以创建新的源或目标,而不是从流派生。要为新类型创建输出运算符,您将使用operator<<()作为第一个参数并将自定义类型作为第二个参数重载std::ostream&。与std::istream&一样。

BTW,您遇到的问题是因为std::endl是一个功能模板。尝试在某处传递函数模板需要可以推导出适当的实例化。由于输出运算符未覆盖合适的签名,因此无法推导出std::endl的实例化。我可以说明需要什么,但这样做毫无意义,因为无论如何都是错误的方式。

答案 1 :(得分:1)

以下是如何编译代码:http://pastebin.com/xAt5junf

相关摘录:

class Message : public ostringstream
{
public:
    Message() {};
    virtual ~Message() {};
};

ostream& operator <<(ostream &os, const MyTypeA &a) {
    return os << a.getStr();
};

ostream& operator <<(ostream &os, const MyTypeB &b) {
    return os << b.getStr();
};