samedi 7 mars 2015

A better workaround for recursive template forward declaration?

I have a potentially recursive templated struct type (effectively a c++11 version of boost::variant), and unfortunately, the nicest workaround I can come up with involves macros, which I would REALLY like to avoid.


So given this type:



template<typename... T>
struct MyType {
using MyType_parent_t = Mytype<T...>;
/*lots more code*/
} ;


I want to be able to do the equivalent of the following:



struct value;

using value = MyType<
bool,
int,
float,
std::string,
std::vector<value>,
std::map<std::string,value>
>;


Now, obviously, this doesn't work, as I can't forward declare a templated struct (which I feel I should in this scenario, but whatever).


Now, here's what I've got right now:



struct value : public MyType<
int,
double,
bool,
std::string,
std::map<std::string, value>,
std::vector<value>
> { INJECT_PASSTHROUGH_WRAPPER_BOILERPLATE(value) };


where INJECT_PASSTHROUGH_WRAPPER_BOILERPLATE(value) will expand to:



value() = default;
value(value const & ) = default;
value(value &&) = default;

template<typename T,
typename std::enable_if<NonSelf<T, value>()>::type* = nullptr>
value(T && op) : MyType_parent_t(std::forward<T>(op)) { }

value & operator=(value const &) = default;
value & operator=(value &&) = default;
template<typename T,
typename std::enable_if<NonSelf<T, value>()>::type* = nullptr>
value & operator=(T && val) {
*static_cast<MyType_parent_t*>(this) = val ;
return *this;
}


The big problem is that I need the wrapper type to have a forwarding constructor and forwarding assignment, so I need a ton of boilerplate to accomodate it.


I actually kinda dig this solution, as I don't even need a forward declare anything anymore (as long as recursivity is done through containers). I just reaaaaaaaly wish I could pull this off without macros, but at this point, it's time for me to ask for help.


Any suggestions? (I am open to c++14, or even c++1z options if necessary)


Aucun commentaire:

Enregistrer un commentaire