如何实现获取std::variant成员类型指针构成的新std::variant的Trait?
实现std::variant的指针类型转换Trait
针对你需要将std::variant的每个成员类型转为指针类型并生成新std::variant的需求,有两种直接的实现方式:
方法一:参数包直接展开(最简洁)
利用模板特化直接展开原std::variant的参数包,将每个类型替换为对应的指针类型:
#include <variant> // 主模板,仅对std::variant做特化 template<typename T> struct pointer_of_v; // 特化处理std::variant<Ts...> template<typename... Ts> struct pointer_of_v<std::variant<Ts...>> { using type = std::variant<Ts*...>; }; // 辅助别名,简化使用 template<typename T> using pointer_of_v_t = typename pointer_of_v<T>::type; // 验证示例 int main() { using MyVariant = std::variant<int, float>; using MyPointerVariant = pointer_of_v_t<MyVariant>; // 确认类型匹配:std::variant<int*, float*> static_assert(std::is_same_v<MyPointerVariant, std::variant<int*, float*>>); }
方法二:通过索引序列遍历(贴合variant_size/variant_alternative思路)
如果你希望用std::variant_size_v和std::variant_alternative_t来实现,可以借助索引序列遍历原variant的每个成员类型:
#include <variant> #include <utility> #include <type_traits> // 辅助模板,接收variant类型和索引序列 template<typename Variant, std::size_t... Is> struct pointer_of_v_impl { // 遍历每个索引,获取对应类型并转为指针,再打包成新variant using type = std::variant<std::add_pointer_t<std::variant_alternative_t<Is, Variant>>...>; }; // 主模板 template<typename T> struct pointer_of_v; // 特化std::variant,生成对应长度的索引序列传递给辅助模板 template<typename... Ts> struct pointer_of_v<std::variant<Ts...>> : pointer_of_v_impl<std::variant<Ts...>, std::make_index_sequence<sizeof...(Ts)>> {}; // 辅助别名 template<typename T> using pointer_of_v_t = typename pointer_of_v<T>::type; // 验证示例 int main() { using MyVariant = std::variant<int, float, double>; using MyPointerVariant = pointer_of_v_t<MyVariant>; static_assert(std::is_same_v<MyPointerVariant, std::variant<int*, float*, double*>>); }
两种方法都能实现需求,第一种更简洁直观,第二种则贴合你最初尝试的索引遍历思路。
内容的提问来源于stack exchange,提问作者MaPo
相关产品推荐
相关产品推荐

