无需decltype与宏的STL容器size_type类型推导模板实现方案咨询
无需decltype与宏的STL容器size_type类型推导模板实现方案咨询
嘿,这个学术练习挺有意思的!我理解你想摆脱每次都写decltype的麻烦,直接用变量名来推导它的size_type——毕竟谁不想让代码更简洁呢?
先分析下你当前遇到的问题:你的AUTO_SIZE_T模板需要的是类型参数,但ints是一个变量而不是类型,直接传AUTO_SIZE_T<ints>会因为模板参数不匹配而编译报错。下面根据不同的C++标准,给你几个可行的方案:
方案1:C++20 静态存储期变量专属写法
如果你使用C20,并且你的容器是全局变量或者static局部变量(具有静态存储期),可以利用C20新增的auto非类型模板参数来实现你想要的AUTO_SIZE_T<ints>写法:
#include <iostream> #include <vector> #include <type_traits> // 绑定容器变量的引用,推导其size_type template <auto& Container> using AUTO_SIZE_T = typename std::remove_reference_t<decltype(Container)>::size_type; // 全局静态容器 static std::vector<int> global_ints = {1, 2, 3}; int main() { // static局部容器 static std::vector<int> local_static_ints = {4, 5, 6}; // 直接用变量名作为模板参数 for (AUTO_SIZE_T<global_ints> i = 0; i < global_ints.size(); ++i) { std::cout << global_ints[i] << std::endl; } for (AUTO_SIZE_T<local_static_ints> i = 0; i < local_static_ints.size(); ++i) { std::cout << local_static_ints[i] << std::endl; } }
不过要注意:普通的非静态局部变量不能用这个方案,因为C++20不允许将非静态局部变量的引用作为非类型模板参数(它的地址不是编译时常量)。
方案2:通用简洁写法(无需额外模板)
如果是普通的局部变量,最优雅的非宏方案其实不需要额外写模板,直接结合decltype和auto初始化就能达到简洁的效果:
#include <iostream> #include <vector> int main() { std::vector<int> ints = {1, 2, 3}; // 直接推导类型,无需手动写decltype到模板里 for (auto i = decltype(ints)::size_type{0}; i < ints.size(); ++i) { std::cout << ints[i] << std::endl; } }
这种写法比你原来的AUTO_SIZE_T<decltype(ints)>更短,也完全符合你的需求——不需要宏,也不用额外维护模板。
为什么没有完美匹配局部变量的AUTO_SIZE_T<ints>写法?
遗憾的是,在C20之前,模板参数只能是类型或者编译时常量值,无法直接接受普通局部变量;而C20也仅支持静态存储期变量的引用作为非类型参数。如果一定要用AUTO_SIZE_T<ints>处理普通局部变量,那只能借助宏,但你明确拒绝了宏,所以目前没有符合要求的方案。
不过话说回来,上面的第二种写法已经足够简洁,完全能满足日常代码的需求啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

