c++ - 继承自 std::ostringstream

标签 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 << a << "-") 将返回一个 ostringstream&,它不能接受 'b'。所以我使用模板来确保始终返回 Message&。

我的问题:

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

生成一个非常长的编译器错误,我不知道为什么。

Here是我的问题的一个简约的“不”可编译示例,并且 here是相应的编译器输出。

最佳答案

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

顺便说一句,你遇到的问题是因为std::endl是一个函数模板。试图在某处传递函数模板需要可以推导出适当的实例化。由于您的输出运算符没有包含合适的签名,因此 std::endl 的实例化无法推断。我可以说明需要什么,但这毫无意义,因为无论如何这是错误的方法。

关于c++ - 继承自 std::ostringstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23726848/

相关文章:

c++ - 从另一个序列初始化 Boost.Fusion 序列的元素

c++ - 使用条件确定字符串中的元素

c++ - 如何定义 std::ostringstream 的上限,之后所有附加数据都将被丢弃?

c++ - "error: invalid operands of types ' int ' and ' const char [2] ' to binary ' 运算符<< '|"

c++ - 将字符串中的数据提取到映射中的有效方法是什么?

ruby-on-rails - 如何在 Rails 中制作 UI 组件?

c++ - 为什么我必须将这些引用参数声明为 const 或按值传递?

c++ - Stringstream 到字符串逻辑 C++

c++ - glGenBuffers 2 名称?

c++ - Mac OS X 链接器