На самом деле я никогда не использовал на практике политику на основе политик, и с тех пор, как я написал код на C ++, прошло много времени, но вот моя интерпретация.Как вы указали, класс хоста может налагать ограничения на политики, используемые с ним, либо через интерфейсы, либо через что-то вроде using output_policy::Print;
, как показано в вики-примере.
Преимущество (или различие)метод использования заключается в том, что он менее проактивен и менее жесток, поскольку у политик есть подразумеваемый контракт, который представлен непосредственно кодом, который их использует.В примере использования, учитывая текущее состояние кода, реализация output_policy должна реализовывать только метод с именем Print, который возвращает что угодно и принимает то, что возвращает language_policy :: Message () (в этом случае все language_policies возвращают std :: string),Это немного ближе к типу утки.
Один недостаток заключается в том, что подразумеваемый контракт исчезает, когда код исчезает.Другим недостатком является то, что политики имеют определенный уровень зависимости друг от друга.В качестве очень надуманного примера, если у одного output_policy есть неуниверсальный метод Print, который печатает только строки, его нельзя использовать с language_policy, который печатает только целые числа.
Я не понимаю, почему вы не можете добавитьинтерфейсы политики, если это необходимо.Один пример - это когда класс HelloWorld может захотеть ограничить output_policy, чтобы он печатал строки и ничего больше.Вы можете достичь этого, написав что-то вроде следующего: обратите внимание, что вам нужно использовать SFINAE, чтобы принудительно реализовать output_policy<std::string>
OutputPolicyInterface<std::string>
.
template<typename message_type>
class OutputPolicyInterface
{
virtual void Print( message_type message ) = 0;
};
template <template<class> class output_policy, typename language_policy>
class HelloWorld : public output_policy<std::string>, public language_policy
{
public:
void Run()
{
Print( Message() );
//Print(2); won't work anymore
}
};