0

While trying some mutex-locked print function, I got an idea like this:

class MyWriteStream
{
public:
    MyWriteStream(std::ostream &stream) : stream_(std::move(stream)) {}

    void write(const char *str, const size_t size)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        stream_.write(str, size);
    }

    friend MyWriteStream & operator << (MyWriteStream &out, const char *c);

private:
    std::ostream &&stream_;
    std::mutex mutex_;
};

MyWriteStream & operator << (MyWriteStream &out, const char *c)
{
    out.write(c, strlen(c) * sizeof(char));
    return out;
}

And while calling, I did something like this:

MyWriteStream stream(std::cout);
auto blah = [&stream](const char *s) {
    stream << s << "\n";
};
std::vector<std::thread> threads;
for (auto i = 0; i<10; ++i) {
    std::string str = "blah : " + std::to_string(i);
    threads.push_back(std::thread(blah, str.c_str()));
}
for (auto &thread : threads) {
    thread.join();
}

std::cout << "hello" << std::endl;  // Still Works

It appears I didn't manage to move std::cout, as next line still works. What has happened? Could std::move also bind reference? Also, if I were to make it into usable class, was this a bad idea? [Edit] It does look like bad idea, as there is issue with synchronization. I'm trying to understand same. Any hints are most welcome. I guess, I need to study r-value references in more depth.

user2338150
  • 479
  • 5
  • 14
  • 4
    `std::move` doesn't move. See https://stackoverflow.com/a/27026280. – L. F. Feb 15 '20 at 08:47
  • I tracked it down to resource management issue. Problem was the caller. Pointer, str.c_str() was destroyed long before thread was created. Assuming same stack space for locals, this was hit or miss. I changed it to RAII std::string, and it appears to work! – user2338150 Feb 15 '20 at 10:45

0 Answers0