Serious programs
Leyendo esta entrada me he encontrado con la imagen siguiente, que a su vez viene de Thinking Forth:


template
) en el que la versión por defecto no hiciera nada (no hay log), y la versión activada enviaba la salida al log. He aquí una posible implementación:
#include <iostream>
class logger_base
{
public:
logger_base (std::ostream& s)
: s_ (s)
{
}
protected:
std::ostream& s_;
};
template <bool b>
class logger: public logger_base
{
public:
logger (std::ostream& s)
: logger_base (s)
{
}
template <typename T>
friend logger<b>&
operator<< (logger<b> const& l, T const& t)
{
// Default: do nothing
return const_cast<logger<b>&>(l);
}
template <typename T>
friend logger<b>&
operator<< (logger<b> const& l, char const* t)
{
// Default: do nothing
return const_cast<logger<b>&>(l);
}
};
template<>
class logger<true> : public logger_base
{
public:
logger (std::ostream& s)
: logger_base (s)
{
}
template <typename T>
friend logger<true>&
operator<< (logger<true> const& l, T const& t)
{
// Do now: log
logger<true>& _l = const_cast<logger<true>&>(l);
_l.s_ << t;
return _l;
}
template <typename T>
friend logger<true>&
operator<< (logger<true> const& l, char*const t)
{
// Do now: log
logger<true>& _l = const_cast<logger<true>&>(l);
_l.s_ << t;
return _l;
}
};
// DO LOG
typedef logger<true> logger_t;
int
main (int argc, char**argv)
{
logger_t log (std::cout);
log << "abc" << "cde";
return 0;
}
logger<T>
implementa el operator<<
de tal forma que no hace absolutamete nada. La clase acepta cualquier std::ostream
, con lo que se puede mostrar por pantalla o por cualquier fichero, socket, etc.logger_t
como un typedef
del logger adecuado, y utilizar a partir de ese momento logger_t
durante todo el código.
main:
.LFB1037:
subq $8, %rsp
.LCFI1:
movl $3, %edx
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
movl $3, %edx
movl $.LC1, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
xorl %eax, %eax
addq $8, %rsp
ret
ostream::insert
dos veces (con las dos cadenas), y el log se produce. Ahora para el caso "false" (también con -O2):
main:
.LFB1037:
xorl %eax, %eax
ret
Rolleiflex SL 66 + Rollei Planar HFT 80mm/2.8 + Fuji RAP 100F. Wide open.
En el restaurante de la Santa de Totana. Muy bueno, por cierto.