Re: Наследование std::ostream и форматирование вывода
От: Sergey Россия  
Дата: 25.03.09 19:30
Оценка:
Здравствуйте, Madkinder, Вы писали:

M>Доброго времени суток, all.

M>Есть задача писать в поток древовидную структуру данных, каждый из узлов дерева представляет собой либо целое число, либо вещественное число, либо строку символов.

M>Проблема №1

M>Каждый из типов данных должен быть специально отформатирован. Для вещественного и целого типов форматирование можно порулить модификаторами dec, scientific, showpoint, setprecision и им подобным.

M>Все строки должны быть взяты в кавычки. Хотелось бы получить такой функционал посредством создания своего модификатора, что-то в роде:


Я в таких случаях обычно завожу вспомогательный тип — например
template <class T> struct quoted_t
{
    T const &v_;
    explicit quoted_t(T const &v) : v_(v) {}
};


для которого переопределяю оператор вывода, который и ставит кавычки, эскейпит запрещенные символы и т.д.. и вспомогательную шаблонную функцию
template<class T> quoted_t<T> quoted(T const& t)
{ return quoted_t<T>(t); }


Функция, как не трудно догадаться, нужна только для того чтобы не нужно было писать тип, которым инстанцируется quoted_t. Если закавычивать надо только строки, то шаблоны и функция она не нужны.

M>Проблема №2

M>Т.к. выводить нужно древовидную структуру, то хотелось бы отбивать уровень дерева tab-ами. Опять же используя модификатор. setw и setfill не подходят, т.к заранее неизвестно, сколько символов будет в текстовом представлении выводимой переменной.

M>Первое решение, которое пришло в голову -- унаследоваться от std::ostream, добавить методы settablevel(int) и перегрузить ostream& operator<<(ostream&, const & std::string). Но как потом заставить это работать и с fstream и со stringstream, ведь они наследуют ostream, но ни как не мой самопальный класс.


Тут вопрос — какой уровень автоматизма требуется. Если устраивает что-то вроде
ident i;
s << i << quoted("level 0") << endl
  << i << quoted("level 0 again") << endl
  << ++i << quoted("level 1") << endl
  << --i << quoted("level 0") << endl;


то это относительно несложно организовать. Если хочется что-то другое — опишите задачу подробнее.


M>Следующее, что подумалось -- boost::iostreams. Ранее с boost-ом сталкиваться не приходилось, и беглый осмотр iostreams не дал результатов.


Это вообще не про то.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.