如何通过变量访问内部typedef类型(以std::unordered_map为例)
借助已有容器变量推导嵌套类型的几种方法
嘿,这个需求太常见了——谁愿意反复敲那些冗长的容器类型声明啊!在C++11及以后的标准里,我们有好几种优雅的方式来解决这个问题,不用重复写std::unordered_map<aaa, bbb>::iterator这类代码。下面给你逐个拆解:
1. 直接用decltype访问嵌套类型
decltype是C++11引入的关键字,它能推导变量的类型。我们可以直接用它获取已有容器的类型,再访问其嵌套的iterator、const_iterator等类型:
#include <iostream> #include <unordered_map> std::unordered_map<int, int> test() { return {{1, 2}, {3, 4}}; } int main() { // 非const容器对象 auto map = test(); // 用decltype(map)获取容器类型,直接访问iterator decltype(map)::iterator it = map.begin(); std::cout << "Key: " << it->first << ", Value: " << it->second << "\n"; // const引用的容器对象 const auto& const_map = test(); // 对应使用const_iterator,这里decltype会保留const属性 decltype(const_map)::const_iterator const_it = const_map.begin(); std::cout << "Const Key: " << const_it->first << ", Const Value: " << const_it->second << "\n"; return 0; }
如果你的容器是引用类型(比如上面的const_map),担心decltype返回的是引用类型影响嵌套类型访问的话,可以用std::remove_reference_t来剥离引用:
std::remove_reference_t<decltype(const_map)>::const_iterator const_it = const_map.begin();
不过实际上C++标准允许通过引用类型直接访问嵌套类型,所以上面的写法是完全没问题的,这步只是可选的保险操作。
2. 用using定义别名(适合多次复用)
如果需要多次用到容器的嵌套类型,先给decltype推导出来的类型起个短别名会更方便:
int main() { auto map = test(); // 给容器类型起别名 using MyMap = decltype(map); // 之后就可以用MyMap来访问所有嵌套类型 MyMap::iterator it = map.begin(); MyMap::const_iterator const_it = map.cbegin(); MyMap::value_type pair = {5, 6}; // 键值对类型 // 甚至可以给迭代器再单独起别名 using MyMapIter = MyMap::iterator; MyMapIter another_it = map.find(3); }
3. 直接用auto推导迭代器变量(最常用)
如果你的目的只是声明一个迭代器变量,那直接用auto推导是最简洁的方式——连decltype都不用写:
int main() { auto map = test(); // 让auto自动推导iterator类型 auto it = map.begin(); // 要const迭代器的话,用cbegin() auto const_it = map.cbegin(); // 反向迭代器也一样 auto reverse_it = map.rbegin(); }
这也是日常开发中最推荐的写法,代码简洁还不容易出错。
4. C++17:用auto简化同类型容器声明
如果需要创建另一个同类型的容器,C++17允许我们在模板参数中直接用auto推导,或者用decltype直接声明:
int main() { auto map = test(); // C++17支持:直接用auto作为模板参数推导类型 std::unordered_map another_map = map; // 或者用decltype声明空容器 decltype(map) empty_map; }
总结一下:
- 偶尔用一次嵌套类型:用
decltype(map)::iterator - 多次复用类型:先
using定义别名 - 只是声明迭代器变量:直接用
auto(首选) - 声明同类型容器:C++17用
std::unordered_map auto或decltype(map)
内容的提问来源于stack exchange,提问作者TesX
相关产品推荐
相关产品推荐

