Как перегрузить оператор <<? - PullRequest
0 голосов
/ 15 июля 2009

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

Так что я решил перегрузить << со следующей подписью </p>

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

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

ошибка C2666: 'оператор <<': 6 перегрузок имеют похожие преобразования </p>

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

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

Ответы [ 5 ]

5 голосов
/ 15 июля 2009

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

2 голосов
/ 15 июля 2009

Проблема в том, что 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 *.

2 голосов
/ 15 июля 2009

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

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

Как это:

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;
}
  • написать свой собственный streambuf, который делегирует ввод / вывод, в std :: filebuf (это слишком сложно, чтобы привести здесь пример, поиск в web - фильтрация streambuf - хорошее ключевое слово для этого. Если я правильно помню , boost имеет вспомогательную библиотеку для того, что может быть полезно. Обратите внимание, что в этом случае вы, вероятно, в конечном итоге будете использовать другой тип, который является fstream, но который будет наследоваться от ostream.
2 голосов
/ 15 июля 2009

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

1 голос
/ 15 июля 2009

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

...