使用转换后的“boost::mpl::vector”进行标记调度

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

本文关键字:调度 vector mpl 转换 boost      更新时间:2023-10-16

我正在尝试将 tag-dispatch 标记为具有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{});
}

科里鲁演示

如您所见,目标是在initializedestroy中有两个进程可以访问Stuff包。但是,正如这里回答的那样,boost::mpl::reverse<InitOrder>::type实际上不是boost::mpl::vector,并且调度失败:

主.cpp:27:2:错误:调用"销毁"没有匹配函数        destroy(typename boost::mpl::reverse::type{}(;        ^~~~~~~主.cpp:18:6:注意:候选模板被忽略:无法将"矢量"与"v_item"匹配虚空破坏(boost::mpl::vector( {     ^
  • 如何轻松地在两个方向上操作类型列表?
  • Boost.MPL 本质上与可变参数模板不兼容吗?

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

Boost.MPL 本质上与可变参数模板不兼容吗?

基本上。 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>,因此可以按照您想要的方式使用。