У меня есть два типа понтейнера которые принимают по 3 шаблонных параметра
template<class T, class Deferred, class Deadline>
struct prio_container;
template<class T, class Deferred, class Deadline>
struct queue_container;
Deferred и Deadline это плагины, которые расширяют функционал. Все делается без палиморфизма, исключительно на этапе компиляции (статический полиморфизм).
Я хочу абстрагироваться от конкретных реализаций и сделать интерфейс, который бы через указание шаблонных параметров выбирал нужную специализацию. Притом даже сам тип контейнера для пользователя выглядил бы как подключаемый плагин. А так же отвязаться от порядка задания параметром шаблона, и необходимости указывать их все, даже если они не используются. Вот пример того что я пытаюсь сделать.
template<class T,
class Plugin1 = disable_plugin,
class Plugin2 = disable_plugin,
class Plugin3 = disable_plugin>
struct container;
Я смог додуматься только до перечисление всех возможных специализаций. Но это издец как муторно. и если появятся новые плагины то пиши пропало, число комбинаций перевалит за разумный предел.
#include <iostream>
#include <string>
using namespace std;
#define static_type(name) \
static const std::string& type() \
{ \
static std::string type_(name); \
return type_; \
} \
struct prio_plugin;
struct dis_prio_plugin;
struct deferred_plugin
{ static_type("deferred"); };
struct deadline_plugin
{ static_type("deadline"); };
struct disable_plugin
{ static_type("disable"); };
template<class T, class Deferred, class Deadline>
struct prio_container
{
static const std::string& type()
{
static std::string type_("prio_container<" +
Deferred::type() + ", " +
Deadline::type() + ">");
return type_;
}
};
template<class T, class Deferred, class Deadline>
struct queue_container
{
static const std::string& type()
{
static std::string type_("queue_container<" +
Deferred::type() + ", " +
Deadline::type() + ">");
return type_;
}
};
template<class T,
class Plugin1 = disable_plugin,
class Plugin2 = disable_plugin,
class Plugin3 = disable_plugin>
struct container;
template<class T,
class Plugin1,
class Plugin2>
struct container<T, prio_plugin, Plugin1, Plugin2>
{
typedef prio_container<T, Plugin1, Plugin2> type;
};
template<class T, class DisableDeadline>
struct container<T, prio_plugin, deferred_plugin, DisableDeadline>
{
typedef prio_container<T, deferred_plugin, DisableDeadline> type;
};
template<class T, class DisableDeferred>
struct container<T, prio_plugin, deadline_plugin, DisableDeferred>
{
typedef prio_container<T, DisableDeferred, deadline_plugin> type;
};
template<class T>
struct container<T, prio_plugin, deadline_plugin, deferred_plugin>
{
typedef prio_container<T, deferred_plugin, deadline_plugin> type;
};
template<class T>
struct container<T, prio_plugin, deferred_plugin, deadline_plugin>
{
typedef prio_container<T, deferred_plugin, deadline_plugin> type;
};
int main()
{
cout << "Hello World" << endl;
cout << container<int, prio_plugin>::type::type() << std::endl;
cout << container<int, prio_plugin, deadline_plugin>::type::type() << std::endl;
cout << container<int, prio_plugin, deferred_plugin>::type::type() << std::endl;
cout << container<int, prio_plugin, deferred_plugin, deadline_plugin>::type::type() << std::endl;
cout << container<int, prio_plugin, deadline_plugin, deferred_plugin>::type::type() << std::endl;
return 0;
}
prio_container<disable, disable>
prio_container<disable, deadline>
prio_container<deferred, disable>
prio_container<deferred, deadline>
prio_container<deferred, deadline>