I have some class Builder
which builds an Object
. I have plans to replace some of the Object
's guts with policy objects, for example being able to set some container type Storage
. Specifically, I'd like to use the Builder
to set policy objects of the Object
, falling back to some default if none are specified; off the top of my head, something like so:
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()
The crux of the question is: can I use a typedef as a sort of "template variable" so I can store a user defined template variable?
To provide some more context, the Builder
has to support creating a fairly complicated Object
from a json config file, delegating each key and its validation to an individual method. I have a static named constructor Builder::from_config(...)
and a method Builder::load_config(...)
that do that for me, but I want to support picking the policy object from the config file. Otherwise I would be fine with just adding templates to the Builder::init()
method so I could pass my policy objects to the Object
.
I don't understand what you exactly want but...
The crux of the question is: can I use a typedef as a sort of "template variable" so I can store a user defined template variable?
I don't think so; a type can be a template parameter, not a variable; so a typedef is a fixed entity and (as far I know) can't be changed.
Moreover:
typedef std::vector Storage;
doesn't work because std::vector<int>
is a type but std::vector
isn't.
But std::vector
can be a template-template parameter.
The best I can imagine, to help you, is a internal template struct Storage
with a template-template parameter.
The following is a compilable example
#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>>{}, "!");
}