我要解决的问题是根据专门针对每种类型的constexpr模板化函数的返回值对模板参数包进行排序。
我有大约100 BOOST_STRONG_TYPEDEF
s创建类型的列表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] 删除。
我来说两句