Boost logo

Boost :

Subject: Re: [boost] [log] How to derive from a logger
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2010-03-22 15:29:56


On 22.03.2010 19:45, Andreas Huber wrote:
> I guess I can answer my own question now: It's probably not a good idea,
> because of this function in the base class
>
> FinalT& operator= (FinalT that)
> {
> base_type::swap_unlocked(that);
> return static_cast< FinalT& >(*this);
> }
>
> FinalT would in this case not point to the most-derived type, making
> this a very strange operator=.

Right. There are also other members that you'd have to override in order
to bring your members into play with standard macros.

> My question now is: How do I derive my own logger that has its own data
> member(s) without having to duplicate ctors, etc. So far I've come up
> with this ...
>
> ... but this of course leaves minimumSeverity uninitialized. I tried to
> implement default & copy ctor myself & use
> BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD, but that left me with
> strange errors.

Composite loggers are not intended to be derived from. I wonder why you
need to derive in the first place. It is much easier and safer to create
a logger feature and inject it into the logger:

   template< typename BaseT >
   class MyFeature :
     public BaseT
   {
   public:
     typedef typename BaseT::record_type record_type;

   public:
     MyFeature() : minimumSeverity(Default) {}
     MyFeature(MyFeature const& that) :
       BaseT(static_cast< BaseT const& >(that)),
       minimumSeverity(that.minimumSeverity)
     {
     }
     template< typename ArgsT >
     MyFeature(ArgsT const& args) : BaseT(args)
     {
       SetMinimumSeverity(args[keywords::severity | Default]);
     }

     void SetMinimumSeverity(Severity severity);
     Severity GetMinimumSeverity();

   protected:
     template< typename ArgsT >
     record_type open_record_unlocked(ArgsT const& args)
     {
       Severity sev = args[keywords::severity | Default];
       if (sev >= minimumSeverity)
         return BaseT::open_record_unlocked(args);
       else
         return record_type();
     }

   private:
     volatile Severity minimumSeverity;
   };

Then you can define a composite logger with it:

   class MyLogger :
     public basic_composite_logger<
       char,
       MyLogger,
       multi_thread_model< shared_mutex >,
       features< mpl::quote1< MyFeature > >
>
   {
     BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(MyLogger)
   };


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk