Boost MPL排序模板参数包

用户3831357

我要解决的问题是根据专门针对每种类型的constexpr模板化函数的返回值对模板参数包进行排序。

我有大约100 BOOST_STRONG_TYPEDEFs创建类型的列表TYPE_1, TYPE_2, ..., TYPE_N

BOOST_STRONG_TYPEDEF(TYPE_1, int)
BOOST_STRONG_TYPEDEF(TYPE_2, double)
// et cetera
BOOST_STRONG_TYPEDEF(TYPE_N, uint8_t)

然后,我声明一个通用模板constexpr size_t value_of(),专门针对我的每种类型:

template<> constexpr size_t value_of<TYPE_1>() { return 1; }
template<> constexpr size_t value_of<TYPE_2>() { return 2; }
// et cetera
template<> constexpr size_t value_of<TYPE_N>() { return n; }

然后我有一个声明如下的类。我需要UnsortedTypes根据的结果对参数包中的每种类型进行排序value_of

template<typename ...UnsortedTypes>
class MyClass {
  typedef boost::mpl::vector<UnsortedTypes...> UnsortedTypeVector;
  typedef typename boost::mpl::sort<
    UnsortedTypeVector,
    boost::mpl::less<
      boost::mpl::size_t<value_of<boost::mpl::placeholders::_1>()>,
      boost::mpl::size_t<value_of<boost::mpl::placeholders::_2>()>
    >
  >::type SortedTypes;

  // Utility
  void print_types() {
    __print_types<SortedTypes>();
  }

  template<typename Type, typename ...Types>
  void __print_types() {
    std::cout << typeid(Type).name() << "\n";
    if constexpr (sizeof...(Types) > 0) __print_types<Types...>();
  }
};

当我测试如下时:

int main(int, char *[]) {
  MyClass<TYPE_5, TYPE_3, TYPE_4, TYPE_2, TYPE_1> myclass;
  myclass.print_types();
}

我收到了这个巨大的,几乎无法理解的错误消息,它似乎由mpl库中的错误组成。

凭直觉,我怀疑这是由于我的排序谓词定义不正确造成的。但是,我不确定该如何解决!

(这是我第一次使用Boost.MPL,网上没有很多示例,因此请保持谨慎!)

巴里

这是一个简化的示例,可以使发生的事情更加明显:

namespace mpl = boost::mpl;

template <typename T> constexpr size_t value_of() { return sizeof(T); }

template <typename... Ts>
struct X {
    using V = mpl::vector<Ts...>;
    using sorted = typename mpl::sort<
        V,
        mpl::less<
            mpl::size_t<value_of<mpl::_1>()>,
        //              ~~~~~~~~~~~~~~~~~~~
            mpl::size_t<value_of<mpl::_2>()>
            >
        >::type;
};

现在,您打算让这延迟value_of()直到_1被替换为的调用但是实际上发生的是它被立即调用-因为这就是您要的。就我而言,这就是sizeof(_1)最终的结果。因此,由于这些都是常量,因此fullmpl::less<...>只是一些整数常量表达式-而不是您想要的lambda表达式。

您需要做的是通过将谓词变成元函数来确保调用被延迟:

template <typename T>
struct value_of_ : mpl::size_t<sizeof(T)> { };

然后您可以使用:

template <typename... Ts>
struct X {
    using V = mpl::vector<Ts...>;
    using sorted = typename mpl::sort<
        V,
        mpl::less<value_of_<mpl::_1>, value_of_<mpl::_2>>
        >::type;
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章