Как перегрузить оператор <<, который не берет или возвращает ostream

Бустер-карусель не лучший выбор для этой проблемы. Используйте «сова-карусель». По вопросам 2 и 3 вы можете узнать больше о «позиции» в css.

Дополнительная информация по Вопросу 1

Дополнительная информация по Вопросам 2 и 3

.

5
задан Jere.Jones 14 November 2008 в 17:34
поделиться

4 ответа

Можно использовать друга определение, которое определит оператор в окружающем пространстве имен класса и сделает его только видимым к разрешению перегрузки оператора (не вызываемый вручную использование:: оператор <<... синтаксис):

class Logger
{
public:
    Logger();
    ~Logger();

    std::ostream* out_stream;

    template <typename T>
    friend Logger& operator<< (Logger& logger, T thing) {
        *logger.out_stream << thing;
        return logger;
    }

    /* special treatment for std::wstring. just overload the operator! No need
     * to specialize it. */
    friend Logger& operator<< (Logger& logger, const std::wstring & wstr) {
        /* do something here */
    }

};

Альтернатива, для хранения кода, как это - и просто делает оператор <<, обрабатывает друга по шаблону, Вы добавляете эту строку в свое определение класса:

template <typename T>
friend Logger& operator<< (Logger& logger, T thing);

Для проблемы с манипулятором я просто дам Вам свой код, который я пишу некоторое время назад:

#include <iostream>
#include <cstdlib>
using namespace std;

template<typename Char, typename Traits = char_traits<Char> >
struct logger{
    typedef std::basic_ostream<Char, Traits> ostream_type;
    typedef ostream_type& (*manip_type)(ostream_type&);
    logger(ostream_type& os):os(os){}
    logger &operator<<(manip_type pfn) {
        if(pfn == static_cast<manip_type>(std::endl)) {
            time_t t = time(0);
            os << " --- " << ctime(&t) << pfn; 
        } else
            os << pfn;
        return *this; 
    }
    template<typename T> 
    logger &operator<<(T const& t) { 
        os << t; 
        return *this;
    }
private:        
    ostream_type & os;
};

namespace { logger<char> clogged(cout); }
int main() { clogged << "something with log functionality" << std::endl; }

};

Обратите внимание, что это - станд.:: шестнадцатеричное число, но не станд.:: iOS:: шестнадцатеричное число. Последний используется в качестве флага манипулятора для setf функция потоков. Обратите внимание, что для Вашего примера, tho, никакой специальный режим манипуляторов не требуется. Вышеупомянутый специальный режим станд.:: endl только необходим, потому что я действительно передаю время потоком, кроме того, когда станд.:: endl используется.

7
ответ дан 13 December 2019 в 19:38
поделиться

Никакому объявлению дружбы не было нужно:

class Logger
{
public:
    Logger();
    ~Logger();

template <typename T>
inline Logger& Display(T thing)
{
   *out_stream << thing;
    return *this;
}
private:
    std::ostream* out_stream;
};

template <typename T>
Logger& operator<< (Logger& logger, T thing) 
{
    return logger.Display(thing);
}
2
ответ дан 13 December 2019 в 19:38
поделиться

почему бы не это printf путь и использование много метод параметра (с тремя точками...). Это все еще дает Вам большое форматирование питания и не делает его настолько грязным как тогда, когда Вы используете <<.

Например:

Logger("This is my log msg %0X", 45);

Зависните на двух secs и плохо потяните пример кода для Вас.

Править:

void Logger(const char* format, ...)
{
    char szMsg[3000];

    va_list args;
    va_start( args, format );
    vsnprintf( szMsg, sizeof(szMsg) - 1, format, args );
    va_end(args);

    // code to print szMsg to a file or whatever here
}

Если Вы хотите использовать это в качестве класса не одинокая функция, Вы могли бы перегрузить оператор регистратора (), и он будет работать все равно

0
ответ дан 13 December 2019 в 19:38
поделиться

Используя шаблон правильный способ сделать это, но просто необходимо удостовериться, что шаблон находится в заголовочном файле (logger.h, или независимо от того, что Вы звонили), не в файле реализации (logger.cpp). Это будет автоматически работать на любой тип, который имеет operator << определенный с std::ostream. Это будет также автоматически работать с потоковыми объектами манипулятора - это - действительно просто функции, которые берут std::ostream параметр, и operator << просто вызывает функцию на ostream.

Можно сделать operator << друг функция следующим образом:

template <typename T> friend Logger& operator<< (Logger& logger, T thing);

Специализации легки - просто используют шаблонные специализации (снова, в заголовочном файле):

template <typename T>
Logger& operator<< (Logger& logger, T thing) {
    *logger.out_stream << thing;
    return logger;
}

// Template specialization - the "template <>" part is necessary
template <>
Logger& operator<< (Logger& logger, const wchar_t *wstr)
{
  // convert wstr to an ANSI string and log it
}

template <>
Logger& operator<< (Logger& logger, const std::wstring & wstr)
{
  // convert wstr to an ANSI string and log it
}
2
ответ дан 13 December 2019 в 19:38
поделиться
Другие вопросы по тегам:

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