1

我有很多日志记录功能,现在可以接受ostringstream&. 我的目标是让他们能够接受用一行编写的流,如下所示:

MyPrint( ostringstream() << "hello!" << endl);

我无法大幅更改方法原型,因为我有很多仍然可以工作的遗留代码。我想将其更改为,ostream&因为这是<<. 现在原型的形式是:

void MyPrint( <some parameters>, ostringstream& stream)

在阅读此处c++ stringstream to ostream to string后,我建议的更改是(让我们忽略其他参数):

void MyPrint(ostream& stream)
{
    stringstream ss;
    ss << stream.rdbuf();
    cout << "ss is:" << ss.str() << endl;
}

以下行有效:

MyPrint(stringstream().flush() << "hello world!" << endl);

但这会打印一个空白:

ostringstream oss;
oss << "hello world!" << endl;
MyPrint(oss);

stringstream(由于某种原因,这实际上可以与 a 一起使用)

第二种形式必须有效,因为这是我的遗留代码的编写方式。

此外,如果我可以避免像stringstream().flush()我喜欢一个解决方案那样写一些不雅的东西,那么如果你这样做,该线程中的每个解决方案都有效

wrapper() << "string"

但如果你这样做不会编译

wrapper() << "string" << endl

编辑:澄清了我不能破坏的旧原型。

4

2 回答 2

1

<< 的返回类型可以是您想要的任何类型 - 只需创建您自己的类型。唯一真正的限制是 ostringstream 代码必须工作。对 endl 和其他操纵器的支持是微不足道的。看一下这个:

#include <iostream>
#include <sstream>
#include <iomanip>

struct MyStream
{
    mutable std::ostringstream ss;

    MyStream() {}
    MyStream(std::ostringstream & oss) { ss << oss.str(); }
};

typedef std::ostream & (*manipulator_t) (std::ostream &);

const MyStream & operator << (const MyStream & s, manipulator_t m)
{
    s.ss << m;
    return s;
}

template <class T>
const MyStream & operator << (const MyStream & s, T v)
{
    s.ss << v;
    return s;
}

void MyPrint(const MyStream & s)
{
    std::cout << "logged: " << s.ss.str();
}

int main()
{
    MyPrint(MyStream() << "true && false == " << std::boolalpha << (true && false) << std::endl);

    std::ostringstream oss;
    oss << std::setw(22) << "Hello, World!" << std::endl;
    MyPrint(oss);
}

在线演示 -> http://ideone.com/Gm7Cnc

于 2013-08-15T11:03:01.190 回答
1

由于您没有得到太多答复,因此我发布了相同的问题并进行了一些更改。幸运的是,我得到了正确的答案。请看这里

基本上std::stringbufstd::ostringstream支持读取,因为传递的标志不同,因此您没有得到任何输出。

于 2013-08-15T12:31:06.037 回答