У меня есть класс Builder
который строит Object
, У меня есть планы заменить некоторые из Object
кишки с объектами политики, например, возможность установить некоторый тип контейнера Storage
, В частности, я хотел бы использовать Builder
установить объекты политики Object
возврат к некоторому значению по умолчанию, если ничего не указано; от макушки головы, что-то вроде этого:
class Builder {
public
Builder();
// ... builder methods
template<typename S>
Builder& storage() { Storage = S; }
Object init() { return Object<Storage>(...); }
private:
typedef std::vector Storage;
}
template<typename Storage>
class Object { ... }
Object o = Builder()
.storage<std::list>()
.init()
Суть вопроса такова: могу ли я использовать typedef как своего рода «переменную шаблона», чтобы я мог сохранить пользовательскую переменную шаблона?
Чтобы обеспечить больше контекста, Builder
должен поддержать создание довольно сложного Object
из файла конфигурации json, делегируя каждый ключ и его проверку отдельному методу. У меня есть статический конструктор с именем Builder::from_config(...)
и метод Builder::load_config(...)
это делает это для меня, но я хочу поддержать выбор объекта политики из файла конфигурации. В противном случае я буду в порядке, просто добавив шаблоны в Builder::init()
метод, чтобы я мог передать свои объекты политики в Object
,
Я не понимаю, чего именно вы хотите, но …
Суть вопроса такова: могу ли я использовать typedef как своего рода «переменную шаблона», чтобы я мог сохранить пользовательскую переменную шаблона?
Я так не думаю; тип может быть параметром шаблона, а не переменной; поэтому typedef является фиксированной сущностью и (насколько я знаю) не может быть изменен.
Более того:
typedef std::vector Storage;
не работает, потому что std::vector<int>
это тип, но std::vector
нет.
Но std::vector
может быть параметром шаблона-шаблона.
Лучшее, что я могу себе представить, чтобы помочь вам, это внутренняя структура шаблона Storage
с параметром шаблона-шаблона.
Ниже приведен компилируемый пример
#include <list>
template <template <typename ...> class C>
class Object
{ };
class Builder
{
private:
template <template <typename...> class C>
struct Storage
{ Object<C> init() { return Object<C>{}; } };
public:
Builder ()
{ }
template <template <typename...> class C>
Storage<C> & storage() { static Storage<C> ret{}; return ret; }
};
int main ()
{
auto o = Builder{}.storage<std::list>().init();
static_assert(std::is_same<decltype(o), Object<std::list>>{}, "!");
}
Почему не просто
template <template<class...> class StorageT>
class Builder
{
// ...
StorageT<Object> storage_;
};
Builder<std::vector>()...;
Builder<std::list>()...;