如何获取模板类中不依赖模板参数的typedef类型?
关于无需指定T获取A::X类型的问题
哎,这个问题其实挺典型的——先给你个直白结论:绝大多数情况下,你没法完全不指定模板参数T就拿到A
为什么常规写法不行?
模板类A<T>的定义是依赖于T的,A<T>::X这个类型完全可能随着T的变化而改变(比如X可能是T&、std::vector<T>这类和T绑定的类型)。编译器必须知道具体的T,才能确定要实例化哪一个版本的A,进而找到对应的X类型。
可行的变通场景
场景1:X的类型不依赖于T
如果你的A<T>里,X是一个固定不变的类型(比如int、std::string,或者另一个不依赖T的模板类型),那你完全可以随便选一个合法的T来实例化A,从而拿到X。比如:
template<typename T> struct A { // X和T无关,固定为int using X = int; }; // 随便传一个合法的T(比如void)就能拿到X using A_X = typename A<void>::X; // 或者用C++17的auto+decltype更简洁 using A_X = decltype(A<void>::X);
这里因为X不随T变化,所以不管传什么T,拿到的X都是一样的,完全能满足你的需求。
场景2:用模板别名延迟指定T
如果X确实依赖于T,但你只是不想每次写typename A<T>::X这么冗长,那可以用模板别名把这个逻辑封装起来,这样使用时再指定T就行:
template<typename T> struct A { // X依赖于T,比如是T的指针 using X = T*; }; // 封装提取X的逻辑 template<typename T> using A_X = typename A<T>::X; // 使用的时候再指定T A_X<int> ptr; // 等价于A<int>::X ptr; 也就是int* ptr;
这种方式并没有真正“无需指定T”,但把重复的类型提取逻辑封装起来,用起来会清爽很多。
总结
核心逻辑就是:A<T>::X是和T强绑定的,除非X本身和T无关,否则必须让编译器知道具体的T才能确定类型。如果是前者,随便选个T就能拿;如果是后者,只能用模板别名延迟T的指定,最终使用时还是要提供T。
内容的提问来源于stack exchange,提问作者tepsijash
相关产品推荐
相关产品推荐

