Вопрос

Я намерен вызывать функцию всякий раз, когда m_logger<<"hello"<<"world" называется.m_logger имеет тип потока.

Поэтому я решил перегрузить << следующей подписью

friend ofstream& operator<<(ofstream &stream,char *str);

Однако компилятор vc выдает следующую ошибку:

ошибка C2666:'оператор <<':6 перегрузок имеют аналогичные преобразования

Есть ли другой способ добиться этого, моя цель - перенаправить всю операцию записи в объект ofstream на другую функцию?

Создание объекта моего собственного класса работает для меня, однако как я могу заставить его работать как обычный объект потока, который преобразует все типы, определенные системой, в строки или char*.я знаю, что одним из подходов было бы перегрузить оператор для каждого типа, но есть ли более чистый подход

Это было полезно?

Решение

Проблема в том, что ofstream уже перегружен таким образом.Если ты сделаешь mlogger нового типа, обладающего ofstream, то вы можете сделать это:

class mlogger_t {
public:
    ofstream stream;
    ...
}

mlogger_t& operator<<(mlogger_t& stream, const string& str) {
    stream.stream << str;
    ...
}

//EDIT: here is how to make this work for other types too using templates:
template<typename T> mlogger_t& operator<<(mlogger_t& stream, T val) {
    stream.stream << val;
}

...

mlogger_t mlogger;

mlogger << "foo";

Кроме того, вам обязательно следует использовать const string& (как я сделал в этом примере), а не строку в стиле C.Если вы Действительно нужно, чтобы это было в стиле C, хотя бы используйте const char *.

Другие советы

«перегрузка» — это не «переопределение».Вы можете перегрузить функцию или оператор для аргументов разных типов;вы не можете переопределить существующую функцию или оператор своей собственной реализацией (кроме переопределения виртуальных функций, что, очевидно, сильно отличается).Единственными исключениями являются operator new и operator delete, где можно переопределить встроенные.

Вы можете изменить тип объекта m_logger.

В зависимости от того, почему вы хотите перегрузить оператор<<, правильным решением будет либо

  • использовать в качестве целевого потока другой тип, отличный от потомка ostream;в этом случае вам придется написать все операторы << самостоятельно, но вы можете получить помощь от шаблонов, если хотите пересылать по умолчанию.

Так:

template <typename T>
myStream& operator<<(myStream& s, T const& v)
{
    s.getStream() << v;
}

и вы увидите, что манипуляторы не соответствуют шаблону, поэтому вам также понадобится что-то вроде:

myStream& operator<<(myStream& fl, std::ostream& (*fn)(std::ostream&))
{
    s.getStream() << fn;
}
  • написать свой собственный потоковый буфер, который делегирует ввод-вывод в std::filebuf (это слишком сложно, чтобы приводить пример здесь, поищите в Интернете - фильтрация потокового буфера является хорошим ключевым словом для этого.Если я правильно помню, у boost есть вспомогательная библиотека, которая может оказаться полезной.Обратите внимание, что в этом случае вы, вероятно, в конечном итоге будете использовать другой тип, а именно fstream, но который будет потомком ostream.

Что вам нужно сделать, это создать класс, а затем определить operator<<.Перегрузка оператора должна содержать хотя бы один определяемый пользователем тип.Точно так же вы не можете написать новый operator+(int, int).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top