Re[3]: Наследование std::ostream и форматирование вывода
От: Sergey Россия  
Дата: 26.03.09 10:05
Оценка:
"Madkinder" <8566@users.rsdn.ru> wrote in message news:3342774@news.rsdn.ru...

>

    >
  1. Слишком общий, такой гибкости мне не надо, т.к. обрабатывать нужно только строки. Ну, это просто исправить.
    >
  2. Всё-таки используется дополнительный класс-обёртка, а его очень хотелось бы избежать. Слишком велик шанс того, что пользователь класса влепит std::string вместо quoted (а то и строковый литерал). Нельзя ли обойтись без дополнительного класса?
    >

Ну тогда только с наследованием, imho. Правда, как мне кажется, проблем при этом не меньше — все равно кто-нибудь может написать

string val = "_value_";
s << "prefix" << val << "suffix";

ожидая получить на выходе "prefix_value_suffix". Ну и до кучи — предположим, как-то удалось решить вашу проблему без наследования и введения лишнего типа, т.е. все строки выводятся во все стримы закавыченными. Вы абсолютно уверены, что у вас в программе не возникнет ситуация, когда в какой-то стрим не понадобится вывести строку без кавычек? Это я к тому, что как-то отделять обычный вывод строк в потоки от "продвинутого" обычно все-таки требуется.

> Покритикуйте, пожалуйста, упрощённую реализацию. Никаких граблей с неявным преобразованием типов не возникнет?

>
> #include <iostream>
> #include <string>
> 
> class quoted : public std::string {
>        public:
>                explicit quoted(const char * oString) : std::string(oString) { }
>                explicit quoted(const std::string & oString) : std::string(oString) { }
> };
> 
> std::ostream & operator<<(std::ostream & oStream, const quoted & oString) {
>        using std::string;
> 
>        string s(oString.c_str());
> 
>        string::size_type i = static_cast<string::size_type>(0);
> 
>        while ((i = s.find('\"', i)) != string::npos) {
>                s.insert(i, 1, '\\');
>                i += 2;
>        }
> 
>        oStream << "\"" << s << "\"";
>        return oStream;
> }
>


Наследование от строки — зря, лучше сделать ее членом, копия которая называется s — тоже на мой взгляд лишняя, быстрее будет посимвольно выводить. Больше никаких проблем на первый взгляд не вижу.

>

> M>>Проблема №2
>
> S>Тут вопрос — какой уровень автоматизма требуется.
> Если быть точным, то хочется так:
>
> std::fstream s("qwe.txt");
> 
> s << setindent(2) // Каждая последующая новая строка должна быть отбита 2мя tab-ами.
>  << "test" << 123 << std::endl
>  << "yet another test" << 567 << std::endl
>  << setindent(1) // Каждая последующая новая строка должна быть отбита 1м tab-ом.
>  << "test once again" << 890 << std::endl;
>

>
> и на выходе:
>
>
> "test" 123
> "yet another test" 567
> "test once again" 890
>


Если устроит вместо std::endl писать my::endl или скажем newline, то реализация будет тривиальной. Если все-таки хочется именно std::endl в сочетании именно со стандартными стримами, то лично я ничего посоветовать не могу, поскольку считаю подобные решения хождением по граблям и, соответственно, на практике проделывать такое не пробовал. Хотя через наследование или там фильтры из boost::iostreams наверное получится.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.