Как делает QDebug () <<материал; добавить новую строку автоматически?

Я пытаюсь реализовать свое собственное qDebug() разработайте поток вывода отладки, это в основном, что я имею до сих пор:

struct debug
{
#if defined(DEBUG)
    template<typename T>
    std::ostream& operator<<(T const& a) const
    {
        std::cout << a;
        return std::cout;
    }
#else
    template<typename T>
    debug const& operator<<(T const&) const
    {
        return *this;
    }

    /* must handle manipulators (endl) separately:
     * manipulators are functions that take a stream& as argument and return a
     * stream&
     */
    debug const& operator<<(std::ostream& (*manip)(std::ostream&)) const
    {
        // do nothing with the manipulator
        return *this;
    }
#endif
};

Типичное использование:

debug() << "stuff" << "more stuff" << std::endl;

Но я хотел бы не должным быть добавить станд.:: endl;

Мой вопрос в основном, как я могу сказать когда тип возврата operator<< не будет используемым другим operator<< (и тем самым добавьте endl)?

Единственным путем я могу думать для достижения чего-либо как это, должен был бы создать список вещей распечатать со связанным с каждым временным объектом, созданным qDebug(), затем для печати всего, наряду с запаздывающей новой строкой (и я мог сделать умные вещи как вставление пробелов) в ~debug(), но очевидно это не идеально, так как у меня нет гарантии, что временный объект будет уничтоженным до конца объема (или я?).

15
задан AAEM 29 July 2019 в 19:54
поделиться

4 ответа

Qt использует метод, аналогичный @evan. См. версию QDEBUG.H для деталей реализации, но они поток все в базовый текстовый поток, а затем промойте поток и конечную строку на разрушении временного объекта QDebug, возвращаемого QDEBUG () Отказ

10
ответ дан 1 December 2019 в 01:53
поделиться

Вставка потока ( << и извлечение ( >> ) должны быть не члены Отказ

Мой вопрос в основном, как я могу скажи, когда возвратный тип Оператор << не будет использоваться другой оператор << (и так подтверждает EndL)?

Вы не можете. Создайте функцию участника, чтобы специально добавить это или добавить ENDL после того, как эти цепные звонки выполнены. Документе свой класс хорошо, чтобы клиенты знали, как его использовать. Это твоя лучшая ставка.

0
ответ дан 1 December 2019 в 01:53
поделиться

Что-то вроде этого сделает:

struct debug {
    debug() {
    }

    ~debug() {
        std::cerr << m_SS.str() << std::endl;
    }

public:
    // accepts just about anything
    template<class T>
    debug &operator<<(const T &x) {
        m_SS << x;
        return *this;
    }
private:
    std::ostringstream m_SS;
};

, которое должно позволять вам делать такие вещи:

debug() << "hello world";

Я использовал табло, подобную этому в сочетании с блокировкой, чтобы обеспечить, как система регистрации журнала, которая может гарантировать, что записи журнала написано атомно.

Примечание : непроверенный код, но должен работать: -)

17
ответ дан 1 December 2019 в 01:53
поделиться

Когда вы пишете, что это типичное использование:

debug() << "stuff" << "more stuff" << std::endl;

Вы определенно планируете построить объект отладки каждый раз, когда вы его используете? Если это так, вы должны быть в состоянии получить поведение, которое вы хотите, имея делубюзор Destructor, добавьте новую строку:

~debug()
{
    *this << std::endl;

    ... the rest of your destructor ...
}

, что означает, что вы не можете сделать что-то подобное:

// this won't output "line1" and "line2" on separate lines
debug d;
d << "line1";
d << "line2";
5
ответ дан 1 December 2019 в 01:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: