Здравствуйте, Шахтер, Вы писали:
Ш>Ш>enum LogType { Log }; // Это приём я называю глаголом.
Ш>template <class T>
Ш>logger & operator << (LogType,const T &x) { return singleton<logger>::instance() << x ; }
Ш>...
Ш>Log << "Log message" << endl ;
Ш>
+1
Ш>А по поводу индусов -- все индусы, просто в разной степени.
+1
Этот приём я никак не называю, но когда-то я писал свой лог со сложными стратегиями протоколирования и форматирования, со стратегиями многопоточности и введение подобного класса (MessageLogger) резко все улучшило, как для клиентов лога, так и в самом логе:
namespace log
{
enum message_type
{
mtError = -2,
mtWarning = -1,
mtDebug = 0
};
template< typename T >
class MessageLogger
{
public:
MessageLogger( T& log, int mt = mtWarning )
: mt_( mt ),
log_( log )
{};
MessageLogger(const MessageLogger& ml )
: mt_( ml.mt_ ),
log_( ml.log_ )
{}
virtual ~MessageLogger()
{
this->flush();
};
template<typename T>
std::ostream& operator<<(const T& val)
{
collector_ << val;
return collector_;
}
private:
void flush( )
{
const char* mtNames[] =
{
"ERROR",
"Warning"
};
log_ << ( mt_ < 0 ? mtNames[ (mt_ +1 )* -1 ] : "Debug" )
<< ": "
<< collector_.str()
<< std::endl;
}
int mt_;
T& log_;
std::ostringstream collector_;
};
};
template< typename OS >
inline log::MessageLogger<OS>
log_error( OS& os )
{
return log::MessageLogger<OS>( os, log::mtError );
}
#define
int main(int ac, char** av)
{
log_error( std::cerr )
<< "It's show how MessageLogger may be used. "
<< 1234;
}
... << RSDN@Home 1.1.4 stable rev. 510>>