Блог пользователя IlyaCk

Автор IlyaCk, 11 лет назад, По-русски

(Прошу прощения, тут больше я тупил, чем было реально трудностей... Вопрос можно считать закрытым)

Пусть в некотором категорически не олимпиадном, но и не шибко практическом проекте появилось желание сделать такую штуку: создать некий класс Two_ostreams, чтоб потом можно было создать его экземпляр как-то в стиле Two_ostreams log_and_view("log.txt", cerr);, и чтоб каждый вызов log_and_view << a+b, посчитав сумму a+b, писал её сразу и на cerr, и в файл log.txt.

Казалось бы, элементарно:

class Two_ostreams
{
protected:
	ostream &ostr1, &ostr2;
public:
	Two_ostreams(ostream &o1, ostream &o2) : ostr1(o1), ostr2(o2) { } ;
	template<class D> Two_ostreams &operator << (const D &data) 
	{
		ostr1 << data;
		ostr2 << data;
		return *this;
	}
};

Да не тут-то было: оно работает с примитивными типами, для коих перегрузка << стандартна, но всё ломается при попытке использовать вышеизложенный Two_ostreams с классом C, в котором и определяется собственный friend ostream &operator << (ostream&, const C&), и свежеопределённый << используется в одном из методов. Конкретнее, в момент компиляции Two_ostreams ещё нету перегрузки << для C. Полностью переставлять местами, чтобы всё определение C шло раньше всего определения Two_ostreams никуда не годится, т.к. хочется именно использовать Two_ostreams в некоторых методах C.

Это всё вообще имеет красивое решение? или любой способ будет настолько мрачен, что лучше уж везде по два раза повторять flog << blablabla; cerr << blablabla;?

  • Проголосовать: нравится
  • +11
  • Проголосовать: не нравится

»
11 лет назад, # |
  Проголосовать: нравится +16 Проголосовать: не нравится

Перед классом можно объявить функцию, а определить позже.

class C;
friend ostream& operator << (ostream&, const C&);

Ваш код
  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Может, я и туплю. Но предложенный Fefer_Ivan-ом совет явно неточен/неполон/неправилен, т.к. тоже вообще не компилируется ('friend' : not allowed outside of a class definition).

    Предлагается разорвать declaration и definition только у перегрузки ostream& operator << (ostream &, const C&)? Или также у template<class D> Two_ostreams &operator << (const D &data)?

    Пока что, даже повынося вперёд все declaration по максимуму (чтоб на момент первого definition они все уж_е_ были) удалось только превратить compile error в link error.

    Кстати, как насчёт наследования Two_ostreams от ostream — обязательно надо? желательно? нежелательно? ни в коем случае?

»
11 лет назад, # |
  Проголосовать: нравится +11 Проголосовать: не нравится

я ничего не понимаю в c++, но у меня все работает http://pastie.org/7826313