Re[5]: Наследование std::ostream и форматирование вывода
От: Sergey Россия  
Дата: 26.03.09 13:22
Оценка:
"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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.