使用转换后的 `boost::mpl::vector` 进行标签调度

Tag dispatching with transformed `boost::mpl::vector`s

我正在尝试使用 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{});
}

Coliru demo

如您所见,目标是让 initializedestroy 中的两个进程可以访问 Stuff 包。然而,正如回答hereboost::mpl::reverse<InitOrder>::type实际上是不是一个boost::mpl::vector,调度失败:

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) {
     ^

如果需要,我可以放弃 Boost.MPL,前提是替代方案是标准或 Boost。我正在使用 MSVC 14.1。

Is Boost.MPL inherently incompatible with variadic templates?

基本上。 MPL 早于 C++11,因此要使用 MPL,您 需要 使用他们的算法 - 因此他们的序列概念及其迭代器等。几乎可以肯定有一个非常短的,聪明的方法来做到这一点,但我只能通过猜测和检查找到那些。


至少,如果你需要做的只是反向,这在 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;

所以给出:

using InitOrder = typelist<struct Foo, struct Bar, struct Baz>;

那么 reverse<InitOrder> 将是 typelist<struct Baz, struct Bar, struct Foo>,因此可以按照您想要的方式使用。