"Madkinder" <8566@users.rsdn.ru> wrote in message
news:3343032@news.rsdn.ru...
> S>Ну тогда только с наследованием, imho. Правда, как мне кажется, проблем при этом не меньше — все равно кто-нибудь может написать
> > string val = "_value_";
> s << "prefix" << val << "suffix";
>
> S>Вы абсолютно уверены, что у вас в программе не возникнет ситуация, когда в какой-то стрим не понадобится вывести строку без кавычек?
> Это я уже понял ещё при написании прошлого ответа на Ваш пост. Сейчас уже интересна сама возможность реализовать подобное. Даже с наследованием ума не приложу, как можно добиться результата.
Ведь наследоваться-то нужно от ostream, а получить функционал в классах stringstream и fstream.
Да, это я загнул, наследование тут не при чем, тем более что operator<< для строк вовсе и не член стрима. Однако возможности для хака все равно есть — можно сделать нешаблонную версию под нужные типы — она будет использоваться вместо стандартной шаблонной. Правда, добавлять ее в пространство имен std запрещено, но по рукам-то дать некому...
> S>Наследование от строки — зря, лучше сделать ее членом, копия которая называется s — тоже на мой взгляд лишняя, быстрее будет посимвольно выводить. Больше никаких проблем на первый взгляд не вижу.
> Чем чревато наследование от строки? Это запрещено стандартом или где-то могут вылезти другие подводные грабли?
Да ни чем не чревато, чистая вкусовщина (если не рассматривать совсем уж экзотические варианты использования, приводящие к удаления вашей обертки через указатель на строку). Я просто всегда стараюсь использовать максимально слабое кунфу, особенно в библиотечном коде. А раз здесь не требуется, чтобы quoted вел себя как строка, то и не надо этого допускать. А то мало ли как пользователи этот факт используют, потом упаришься совместимость поддерживать.
> S>Если устроит вместо std::endl писать my::endl или скажем newline, то реализация будет тривиальной.
>
> Возможно я чего-то недопонимаю, ведь my::endl будет добавляться после самой строки, в то время, как табы нужно вставлять до неё. Можно ли пример реализации или более подробное описание подхода?
Ну вообще-то комментарий в setindent гласит — "Каждая
последующая новая строка должна быть отбита N tab-ами". Соответственно, достаточно вставлять табы
после начала строки в соответствии с текущей установкой setindent. Заводите самопальный фасет
struct current_tabbing : public std::locale::facet
{
unsigned n_;
current_tabbing(std::size_t refs, unsigned n) : std::locale::facet(refs), n_(n) {}
};
который setindent будет при необходимости добавлять к текущей локали
std::ostream& operator<<(ostream& s, const setindent& v)
{
if (std::has_facet<current_tabbing>(s.getloc()))
std::use_facet<current_tabbing>(s.getloc()).n_ = v.n_;
else
{
current_tabbing *f = new current_tabbing(v.n_);
std::locale l = std::locale(s.getloc(), f);
s.imbue(l);
}
}
и из которого newline будет потом брать n_, чтобы узнать сколько табов выводить.
Хотя тут по-моему вообще имеет смысл уйти от стримов к какой-то вспомогательной обертке над стримами, которая и будет заниматься идентацией и закавычиванием строк.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.