I am trying to tag-dispatch into a function with a reversed copy of a boost::mpl::vector
:
using InitOrder = boost::mpl::vector<
struct Foo,
struct Bar,
struct Baz
>;
template <class... Stuff>
void initialize(boost::mpl::vector<Stuff...>) {
// Initialize in-order
}
template <class... Stuff>
void destroy(boost::mpl::vector<Stuff...>) {
// Exit in-order
}
void initializeAll() {
initialize(InitOrder{});
}
void destroyAll() {
destroy(typename boost::mpl::reverse<InitOrder>::type{});
}
As you can see, the goal is to have two processes in initialize
and destroy
that have access to the Stuff
pack. However, as answered here, boost::mpl::reverse<InitOrder>::type
is actually not a boost::mpl::vector
, and the dispatching fails:
main.cpp:27:2: error: no matching function for call to 'destroy' destroy(typename boost::mpl::reverse::type{}); ^~~~~~~ main.cpp:18:6: note: candidate template ignored: could not match 'vector' against 'v_item' void destroy(boost::mpl::vector) { ^
I can ditch Boost.MPL if needed, provided the alternative is standard or Boost. I'm using MSVC 14.1.
Is Boost.MPL inherently incompatible with variadic templates?
Basically. MPL
predates C++11, so to use MPL, you need to use their algorithms - so their Sequence concept with their Iterators, etc. There's almost certainly a really short, clever way to do this, but I can only ever find those out with guess and check.
At least, if all you need to do is reverse, this is straightforward to implement in C++11:
template <typename...> struct typelist { };
template <typename TL, typeanme R>
struct reverse_impl;
template <typename T, typename... Ts, typename... Us>
struct reverse_impl<typelist<T, Ts...>, typelist<Us...>>
: reverse_impl<typelist<Ts...>, typelist<Us..., T>>
{ };
template <typename... Us>
struct reverse_impl<typelist<>, typelist<Us...>>
{
using type = typelist<Us...>;
};
template <typename TL>
using reverse = typename reverse_impl<TL, typelist<>>::type;
So given:
using InitOrder = typelist<struct Foo, struct Bar, struct Baz>;
Then reverse<InitOrder>
would be typelist<struct Baz, struct Bar, struct Foo>
, and so would be usable in the way you'd want.