c++policy-injection

Applying policy based design question


I've not read the Modern C++ Design book but have found the idea of behavior injection through templates interesting. I am now trying to apply it myself.

I have a class that has a logger that I thought could be injected as a policy. The logger has a log() method which takes an std::string or std::wstring depending on its policy:

// basic_logger.hpp
template<class String>
class basic_logger
{
public:
    typedef String string_type;

    void log(const string_type & s) { ... }
};
typedef basic_logger<std::string> logger;
typedef basic_logger<std::wstring> wlogger;

// reader.hpp
template<class Logger = logger>
class reader
{
public:
    typedef Logger logger_type;

    void read()
    {
        _logger.log("Reading...");
    }

private:
    logger_type _logger;
};

Now the questing is, should the reader take a Logger as an argument, like above, or should it take a String and then instantiate a basic_logger as an instance variable? Like so:

template<class String>
class reader
{
public:
    typedef String string_type;
    typedef basic_logger<string_type> logger_type;

    // ...

private:
    logger_type _logger;
};

What is the right way to go?


Solution

  • To actually be using a policy class, the policy needs to be a template parameter. One example is the char_traits parameter to basic_string, even though that's implemented differently than MC++D's policies, which use inheritance to make use of the empty base class optimization and to allow easy addition to a class's public interface (in a much better way than wrapping each possible method; again, read MC++D). You can still provide a default:

    template<class String, class Logger=basic_logger<String> >
    struct reader : Logger {
      void read() {
        this->log("Reading...");
      }
    };