- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
struct mystream: public std::ostream
{
mystream(std::ostream & o): std::ostream(o.rdbuf()) {}
template <class T>
mystream & operator << (T const & arg)
{
if (enabled_) as_std_ostream() << arg;
return *this;
}
// дерьмо STX
mystream & operator << (std::ostream & (*f)(std::ostream &))
{
if (enabled_) as_std_ostream() << f;
return *this;
}
mystream & operator << (std::ios & (*f)(std::ios &))
{
if (enabled_) as_std_ostream() << f;
return *this;
}
mystream & operator << (std::ios_base & (*f)(std::ios_base &))
{
if (enabled_) as_std_ostream() << f;
return *this;
}
// дерьмо ETX
void enable() { enabled_ = true; }
void disable() { enabled_ = false; }
protected:
bool enabled_;
std::ostream & as_std_ostream() { return *this; }
};
myaut 14.03.2013 00:55 # 0
http://liveworkspace.org/code/1AWg24$118
Dummy00001 14.03.2013 02:08 # +1
"правильно" это делается на уровне streambuf, перекрывая overflow() (и xsputn()).
"правильно" в ковычках потому что в принципе говно.
defecate-plusplus 14.03.2013 07:39 # 0
подкладывать свой streambuf в поток, который disabled - значит делать все форматирования и тратить на это cpu, чтобы в итоге проигнорить конкретно запись символов - не, не катит
roman-kashitsyn 14.03.2013 08:47 # 0
defecate-plusplus 14.03.2013 09:36 # 0
Dummy00001 14.03.2013 14:34 # +1
по крайней мере все штатные operator<<() проверяют goodbits прежде чем что либо делать.
... если подумать, то даже и перекрывать ничего не надо:
("\n" вместо std::endl что бы про проверить как что флушится.)
absolut 14.03.2013 14:49 # 0
defecate-plusplus 14.03.2013 15:04 # 0
execution time: 3.05
Dummy00001 14.03.2013 15:15 # 0
правильно:
я правда про проверку `if (o)` не уверен. по моему опыту когда ставятся fail/eof биты то чистится goodbit. и наоборот. но почему то они все равно разные флаги.
defecate-plusplus 14.03.2013 15:20 # 0
переписывать миллион своих и чужих выводов в поток, теперь проверяющих переданный им ostream& - не вариант
не заморачивайся так сильно, свою проблему я уже решил, и даже сегодня я допёр, почему второй темплейт так и не заработал бы с std::endl
в ГК приведен схематичный пример, в жизни не bool enabled, а более сложная логика
Dummy00001 14.03.2013 16:22 # 0
да. хотя на самом деле именно так оно и должно делатся (и в стандартной библиотеке делается), потому что если поток не good, то ему разрешено по стандарту бросать исключения. чего почти никто никогда не ожидает и не обрабатывает.
"не заморачивайся так сильно"
я этим уже не раз по работе заморачивался. меня эта тема больше не напрягает :)
"в ГК приведен схематичный пример, в жизни не bool enabled, а более сложная логика"
у нас это сделано еще "проще." схематично:
defecate-plusplus 14.03.2013 16:27 # 0
что есть compile-time only
Dummy00001 14.03.2013 16:32 # 0
может мне было правильней написать `if (!enabled())`.
трюк что это раскрывается в:
и если у тебя есть что-то типа:
то это гарантирует что у тебя эта `BigObject.toString()` даже и не вызовется если ничего выводить не надо.
defecate-plusplus 14.03.2013 16:54 # 0
но недостаток макросов в том, что они рано или поздно начинают конфликтовать с нормальными, человеческими идентификаторами
притом, что в v.1 используется синтаксис вида error() << "hello" << std::endl;
trace() << "verbose description" << std::endl;
и мне бы не хотелось настолько всё сломать
Dummy00001 14.03.2013 16:59 # 0
...хм.
:)
шучу шучу. дело вкуса. макросы хороши только тогда когда можно быть увереным в дисциплине коллег их не ломать и ими не злоупотреблять. у нас работает потому что всем поср@ть.
defecate-plusplus 14.03.2013 17:07 # 0
встречается какой-нибудь класс или функция error, и всё летит к чертям
скобки в макросе спасут только наполовину - можно будет хотя бы отличить макрос от части неймспейса и переменных, но это всё равно бомба
Dummy00001 14.03.2013 16:27 # 0
absolut 14.03.2013 09:55 # +1
defecate-plusplus 14.03.2013 10:06 # +5
срыв покровов
absolut 14.03.2013 10:25 # 0
defecate-plusplus 14.03.2013 11:33 # 0
мои компиляторы жаловались, что не могут выбрать и вообще запутались
плюнул и сделал в лоб
defecate-plusplus 14.03.2013 11:42 # +1
ругается потому, что std::endl сама по себе overloaded function, и конкретные указания, какие типы подойдут компилятор выручают
кстати, если std::endl подставить в вариант myaut/LispGovno, то тоже получится ошибка
TarasB 14.03.2013 11:40 # 0
defecate-plusplus 14.03.2013 11:46 # 0
см мой ответ выше почему
TarasB 14.03.2013 11:53 # 0
defecate-plusplus 14.03.2013 12:00 # 0
у компилятора в распоряжении как минимум 2 варианта (для charT = char и для charT = wchar_t), а как максимум - бесконечно
явные перегрузки - например, std::ostream & (*f)(std::ostream &) позволяют компилятору подставить в оператор конкретно std::endl<char, char_traits> и поэтому всё работает
сейчас еще попробую кое-что, ради интереса, но не факт, что уже получится меньше кода, как хотелось какой T компилятор должен вывести для первого шаблона, и какое O для второго, если бы тот работал?
defecate-plusplus 14.03.2013 12:07 # 0
LispGovno 14.03.2013 15:35 # +1
defecate-plusplus 14.03.2013 15:38 # +1
LispGovno 14.03.2013 15:40 # 0
defecate-plusplus 14.03.2013 15:51 # 0
тред-сейф логи, работающие в релизе, с настраиваемым в рантайме уровнем логирования для каждого логирующегося класса и настраиванием направления вывода логов (поток, ротация файлов, udp, whatever)
roman-kashitsyn 14.03.2013 15:42 # 0
вроде ?
defecate-plusplus 14.03.2013 15:46 # 0
LispGovno 09.02.2014 00:49 # 0