У меня есть набор однородных классов политик, которые я хочу передать в качестве политик классу шаблона, PolicyDrivenClass, который принимает некоторое неизвестное количество параметров шаблона политики.
Каждая политика реализует функцию «имени», и я хотел бы иметь возможность запрашивать имена всех политик во время выполнения через PolicyDriveClass::getNames.
У меня есть работающая реализация, но она кажется неуклюжей, особенно с учетом того, что в моем окончательном проекте классы политики будут реализовывать несколько функций, похожих на «имя», хотя, возможно, с другими типами возвращаемых значений, и что мой класс, управляемый политикой, захочет предоставить средства доступа, подобные "getNames" для каждой из этих функций.
Мой вопрос заключается в том, может ли кто-нибудь придумать лучшую реализацию для этого.
Я использую clang++. Моей версии g++ это не нравится.
Вот что у меня есть:
#include <string>
#include <deque>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
template<typename... Policies>
class PolicyDrivenClass
{
public:
template<typename T, typename... Types>
class NameExtractor
{
public:
static deque<string> getNames()
{
deque<string> names = NameExtractor<Types...>::getNames();
names.push_front(T::name());
return names;
}
};
template<typename T>
class NameExtractor<T>
{
public:
static deque<string> getNames()
{
deque<string> ret;
ret.push_back(T::name());
return ret;
}
};
deque<string> getNames() const
{
return NameExtractor<Policies...>().getNames();
}
};
class Policy1
{
public:
static string name(){return "policy 1";}
};
class Policy2
{
public:
static string name(){return "policy 2";}
};
class Policy3
{
public:
static string name(){return "policy 3";}
};
int main()
{
PolicyDrivenClass<Policy1, Policy2, Policy3> c;
deque<string> names = c.getNames();
ostream_iterator<string> out (cerr,"\n");
copy(names.begin(), names.end(), out);
}