I have a class, which boils down to this:
template <typename ...Ts>
class Stuff
{
std::vector<std::variant<std::vector<Ts>...>> v_data;
}
Ts are unique types. Now as far as I understand, excepting for the indices there is no difference between std::variant<A, B>
and std::variant<B, A>
, which means that with some care Stuff should also be order-insensitive. Furthermore, since variants can take only one state at a time there should be no problem in treating Stuff<A>
as Stuff<A, B>
, as long as one doesn't go asking for data of type B from this instance.
Problem is, how do I allow such a conversion? I tried writing a conversion operator:
template <typename ...Ts>
template <typename ...Us>
Stuff<Ts...>::operator const Stuff<Us...>&() const
{
/* some assert ensuring that Us is at least as wide as Ts */
return &(*this);
}
plus a few other versions with static_cast etc, but they fail to compile with some variation of invalid casting of this.
The idea is to store references (_wrapper) to instances of Stuff inside a container and operated on together, and what I don't know what should T be in std::reference_wrapper<T>
that fits all these Stuffs.
A few other things I considered:
having all Stuffs inherit from a non-template type and store references to that: works, but some Stuff member functions takes lambda as arguments and so need to be templates, which can't be virtual
store instead a variant of all possible variations of Stuff references: I don't know how to "explode" the type list ie to go from
Stuff<A, B>
toStuff<A>, Stuff<B>, Stuff<A, B>, Stuff<B, A>
Any suggestions are welcome.
EDIT: Apologies for editing/bumping, but let me elaborate a bit more what I mentioned in the comments.
In Permutation P(N,R) of types in compile time there is a working implementation for type explosion. This would fit my purpose if it can be extend in two ways:
1- A way to "sum" the PermutationN<N, P<A, B, C>>
s from 1 to N. Haven't tried to actually do this yet, due to the difficulty in achieving the next extension, but it's probably related to tuple_cat
somehow
2- instead of wrapping it all under the same wrapper like P<P<A, B>, P<B, A>>
one can use different wrappers say, T<U<A, B>, U<B, A>>
. I tried doing this myself, but since the wrappers I have in mind can't be empty, while the machinery relies on P<>
, I need to somehow translate from P
to T
and U
, which I haven't been very successful at