C++14中用Boost.Hana的hana::transform转换tuple内部类型
如何用Boost.Hana的transform修改tuple_t中的类型
嘿,我来帮你搞定这个Boost.Hana的类型转换问题!你想把hana::tuple_t<int, char*, bool>转换成每个元素都被std::vector包裹的tuple_t,这个需求完全可以通过hana::transform实现,我来拆解正确的写法和你可能踩的坑。
正确实现方式
方式一:Lambda结合hana::unwrap
最直观的写法是用lambda遍历tuple_t的每个元素,借助hana::unwrap获取原始类型,包裹成std::vector后,再用hana::type_c包装回hana::type:
#include <boost/hana.hpp> #include <vector> namespace hana = boost::hana; int main() { constexpr auto some_tuple = hana::tuple_t<int, char*, bool>; constexpr auto transformed_tuple = hana::transform(some_tuple, [](auto type_tag) { // type_tag是hana::type<T>的实例,unwrap后得到对应的原始类型标记 using OriginalType = decltype(hana::unwrap(type_tag)); return hana::type_c<std::vector<OriginalType>>; }); // 验证转换结果是否符合预期 static_assert(hana::equal(transformed_tuple, hana::tuple_t<std::vector<int>, std::vector<char*>, std::vector<bool>>), "类型转换错误"); }
方式二:元函数风格(更简洁)
如果你偏好元编程的写法,可以定义一个元函数模板,再用hana::metafunction把它适配成hana算法可用的函数:
#include <boost/hana.hpp> #include <vector> namespace hana = boost::hana; // 元函数:接收类型T,返回std::vector<T> template <typename T> struct WrapVector { using type = std::vector<T>; }; // 别名模板简化写法(C++14及以上) template <typename T> using WrapVector_t = std::vector<T>; int main() { constexpr auto some_tuple = hana::tuple_t<int, char*, bool>; // 用metafunction适配元函数模板 constexpr auto transformed_tuple = hana::transform(some_tuple, hana::metafunction<WrapVector>); // 或者用metafunction_t适配别名模板 // constexpr auto transformed_tuple = hana::transform(some_tuple, hana::metafunction_t<WrapVector_t>); static_assert(hana::equal(transformed_tuple, hana::tuple_t<std::vector<int>, std::vector<char*>, std::vector<bool>>), "类型转换错误"); }
你原来尝试失败的原因分析
你提到想用hana::transform返回hana::type_c<std::vector<decltype(T)::type>>,这个思路本身是对的,但大概率踩了两个小坑:
- 缺少
typename关键字:decltype(T)::type是依赖类型(依赖于T的具体类型),在模板语境下(lambda本质是模板化的函数对象),必须用typename告诉编译器这是一个类型,正确写法应该是:hana::type_c<std::vector<typename decltype(T)::type>> - 混淆实例与类型:如果lambda参数是
auto T,那么T是hana::type<OriginalType>的实例对象,而非类型,所以不能直接写T::type,必须用decltype(T)::type来获取对应的类型成员。
用hana::unwrap的写法可以避免手动处理typename和依赖类型的问题,代码可读性也更好哦。
内容的提问来源于stack exchange,提问作者Lukas Barth
相关产品推荐
相关产品推荐

