用于将 std::osyncstream 和 std::cout 组合在一起的 C++20 自定义类

loi*_*pez 1 c++ c++20

我想在多线程上下文中使用std::osyncstreamstd::cout而不需要每次都写:

std::osyncstream(std::cout) << "my message" << std:endl;
Run Code Online (Sandbox Code Playgroud)

我想要达到的目标:

streams::synced_cout << "my message" << std:endl;
Run Code Online (Sandbox Code Playgroud)

我做了什么:

namespace streams {
    class _synced_cout {
    private:
        std::osyncstream synced_cout_stream = std::osyncstream(std::cout);

    public:
        template <class T>
        std::osyncstream &&operator<<(const T& value) {
            synced_cout_stream << value;
            return std::move(synced_cout_stream);
        }
    };

    inline static _synced_cout synced_cout = _synced_cout();
}
Run Code Online (Sandbox Code Playgroud)

但是什么都没有显示,我有什么想念的?或者是否存在更简单的解决方案?

T.C*_*.C. 5

osyncstream有点像unique_lock:每个线程都需要构造自己的实例,osyncstream因为对osyncstream自身的访问没有同步。它所做的只是在内部缓冲区中缓冲输出,并最终将其传输到包装的流(或实际上,streambuf)。只有传输步骤是同步的。

osyncstream因此,拥有一个全局是完全没有意义的。如果从多个线程访问,那就是数据竞争;如果没有,osyncstream首先使用没有意义。

传输缓冲输出

  • 当流被销毁或分配给
  • 何时emit在流上显式调用
  • whenflush在流上调用并且流缓冲已emit_on_sync启用。

一个简单的选择是拥有一个特殊类型,osyncstream当与 一起使用时创建一个新对象<<

class _synced_cout {
public:
    template <class T>
    std::osyncstream operator<<(const T& value) const {
        std::osyncstream synced_cout_stream(std::cout);
        synced_cout_stream << value;
        return synced_cout_stream;
    }
};
Run Code Online (Sandbox Code Playgroud)

当返回的临时文件被销毁时,写入它的所有内容都将转移到std::cout.