mercredi 2 novembre 2016

Calling bit shift operator on temporary [duplicate]

This question already has an answer here:

I'm having some problems trying to use the bitshift operator on a temporary object returned by a class method.

The idea is to create a LogEntry object as a temporary, and through the bitshift operator, append values which would be stored in a std::stringstream object for easy formatting.

On the destruction of the temporary, the std::stringstream would dump its contents, however, the destructor gets called before I can append the first string.

A small example:

class LogEntry
{
public:
    LogEntry(LogLevel level, Widget& widget)
        : m_level{level}
        , m_widget{widget}
    {
    }

    ~LogEntry()
    {
        m_widget.dump(m_level, m_out.str());
    }

    template <typename T>
    LogEntry& operator<<(T&& arg) &&
    {
        m_out << arg;

        return *this;
    }

private:
    LogLevel m_level;
    std::stringstream m_out;
    Widget m_widget;
};

Here is the Logger object, who can create LogEntries:

class Logger
{
public:
    Logger::Logger(Widget& widget)
        : m_widget{widget}
    {
    }

    LogEntry&& Logger::logEntry(LogLevel level)
    {
        return std::move(LogEntry(level, m_widget);
    }

private:
    Widget m_widget;
};

The way I plan on using it would be the following:

Widget outputWriter;
Logger myLogger(outputWriter);

myLogger.logEntry(LOG_LEVEL_DEFAULT) << "This is a log" << 1234;

I had to refactor a bit the code to simplify the example, so sorry if some bits might be off.

The main problem is that the destructor of LogEntry gets called before the operator<<, so when appending content to m_out happens, the memory is already corrupted.

Is there any way to prevent the premature destruction of the object returned by Logger::logEntry()?

Aucun commentaire:

Enregistrer un commentaire