提升 MPL 排序模板参数包
Boost MPL Sorting Template Parameter Pack
我试图解决的问题是根据专门针对我正在排序的每种类型的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; }
然后我有一个声明如下的类。我需要根据value_of
的结果对UnsortedTypes
参数包中的每个类型进行排序。
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)
最终的样子。因此,由于这些都是常量,因此完整的mpl::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;
};
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 提升 MPL 排序模板参数包
- 是否可以使用 static_cast 从可变参数枚举创建 boost::mpl::list_c
- MPL占位符在默认模板参数中替换
- 如何将 MPL 类型列表折叠到可变参数容器中
- boost::mpl::apply 仅适用于类型化模板参数
- 使用mpl::if_和integer模板参数选择类型
- 将mpl lambda表达式作为模板参数传递
- Boost::mpl转换操作元函数参数错误