实现一个可被接受为std::ostringstream引用的无操作std::ostringstream

Implementing a no-op std::ostringstream that can be accepted as a std::ostringstream reference

本文关键字:std ostringstream 引用 操作 一个 实现      更新时间:2023-10-16

谁能建议一种方法有一个null std::ostringstream,避免做任何工作的参数传递给它与<< ?

有两个相关的帖子在这里实现无op std::ostream和ostream打印到任何地方,到目前为止最有希望的解决方案是https://stackoverflow.com/a/760353/826203,但当测试它

int main() {
    onullstream os;
    os << 666;
//  std::ostringstream & oss = os; // error C2440: 'initializing' : cannot convert from 'onullstream' to 'std::ostringstream &'
    oss << "hello, world";
}

只能用作os<<666不能用作std::ostringstream &。有出去的路吗?

创建非可操作流的最简单方法是实际上不创建自定义流类,而是禁用现有流。例如,您可以通过将std::ostream的流缓冲区设置为null来禁用格式化:

std::ostringstream out;
out.std::ostream::rdbuf(0);
// any attempt to write anything to out will fail.

如果你需要一个格式化数据失败的流,你可以创建一个不存储任何字节的流缓冲区,它总是成功的。然而,当使用这个流缓冲区时,实际的格式化将被执行:

struct nullbuf: std::streambuf {
    std::streambuf::int_type overflow(std::streambuf::int_type c) {
        return std::char_traits<char>::not_eof(c);
    }
};
// ...
nullbuf            buf;
std::ostringstream out;
out.std::ostream::rdbuf(&buf);

注意,我还建议而不是让函数接受std::ostringstream作为参数。相反,任何不构造流的函数都应该按照std::ostream&传递。如果你现有的接口已经采用std::ostringstream,你可以通过从std::ostringstream派生并适当设置流缓冲区来创建一个空流:

class onullstream
    : private virtual nullbuf
    , public std::ostringstream {
public:
    nullstring()
        : std::ios(this)
        , std::ostringstgream() {
        this->std::ostream::rdbuf(this);
    }
};