C++中如何从模板参数的成员变量类型推导模板类内vector的元素类型
实现从模板参数的成员变量推导vector元素类型
核心实现逻辑
从C++11开始,可借助decltype关键字在编译期直接获取指定成员变量的类型,不需要为每个传入的类型单独编写模板特化,少量代码即可满足需求。
最简实现方式
直接在vector的类型声明位置,用decltype获取模板参数S中variable成员的类型即可:
#include <vector> #include <complex> struct thingA { double variable; }; struct thingB { std::complex<double> variable; }; template <class S> class someClass { // 直接推导S中variable的类型作为vector的元素类型 std::vector<decltype(S::variable)> history; };
注意:这种写法对
public权限的非静态成员完全适用,因为decltype仅做编译期的类型解析,不需要实例化目标类型的对象、也不会涉及成员的实际内存访问。如果需要解析的是private权限的成员,只需要把自定义的萃取模板声明为目标类的友元,就可以正常完成类型推导,不会触发访问权限报错。
可复用的萃取实现
如果后续多个模块都需要用到这个成员类型,可以封装成通用的类型萃取工具,方便全局复用:
// 定义类型萃取模板 template <typename T> struct variable_member_type { using type = decltype(T::variable); }; // 简化用的类型别名,省去写typename和::type的冗余 template <typename T> using variable_member_type_t = typename variable_member_type<T>::type; // 类里直接使用别名即可 template <class S> class someClass { std::vector<variable_member_type_t<S>> history; };
实际使用效果
和原需求的写法完全兼容,不需要额外调整:
someClass<thingA> myInstanceA; // history自动推导为std::vector<double> someClass<thingB> myInstanceB; // history自动推导为std::vector<std::complex<double>>
补充说明
- 只要传入的模板参数里存在名为
variable的成员,就能自动完成类型推导,不需要为每个结构重复编写特化逻辑 - 如果传入的类型没有
variable成员,编译器会在编译阶段直接报推导错误,问题排查效率远高于运行时异常 - 如果后续需要调整获取的成员名,只需要修改萃取模板里的那一行
decltype(T::xxx),不用逐处修改所有用到这个类型的代码
内容的提问来源于stack exchange,提问作者exocortex
相关产品推荐
相关产品推荐

