c++ 11基于范围的for()循环的常见示例总是这样简单:
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };
for ( auto xyz : numbers )
{
std::cout << xyz << std::endl;
}
在这种情况下,xyz是int型。但是,当我们有地图之类的东西时会发生什么呢?本例中变量的类型是什么:
std::map< foo, bar > testing = { /*...blah...*/ };
for ( auto abc : testing )
{
std::cout << abc << std::endl; // ? should this give a foo? a bar?
std::cout << abc->first << std::endl; // ? or is abc an iterator?
}
当要遍历的容器很简单时,看起来基于范围的for()循环会给我们每个项,而不是迭代器。这很好…如果它是迭代器,我们总是要做的第一件事就是解引用它。
但是当涉及到像地图和multimaps这样的东西时,我很困惑。
(我还在g++ 4.4,而基于范围的循环在g++ 4.6+,所以我还没有机会尝试它。)
容器的每个元素都是一个map<K, V>::value_type,它是std::pair<const K, V>的类型定义。因此,在c++ 17或更高版本中,您可以编写
for (auto& [key, value]: myMap) {
std::cout << key << " has value " << value << std::endl;
}
或者是
for (const auto& [key, value]: myMap) {
std::cout << key << " has value " << value << std::endl;
}
如果您不打算修改这些值。
在c++ 11和c++ 14中,您可以使用增强的for循环单独提取每对,然后手动提取键和值:
for (const auto& kv : myMap) {
std::cout << kv.first << " has value " << kv.second << std::endl;
}
如果您想要一个值的只读视图,还可以考虑将kv变量标记为const。
容器的每个元素都是一个map<K, V>::value_type,它是std::pair<const K, V>的类型定义。因此,在c++ 17或更高版本中,您可以编写
for (auto& [key, value]: myMap) {
std::cout << key << " has value " << value << std::endl;
}
或者是
for (const auto& [key, value]: myMap) {
std::cout << key << " has value " << value << std::endl;
}
如果您不打算修改这些值。
在c++ 11和c++ 14中,您可以使用增强的for循环单独提取每对,然后手动提取键和值:
for (const auto& kv : myMap) {
std::cout << kv.first << " has value " << kv.second << std::endl;
}
如果您想要一个值的只读视图,还可以考虑将kv变量标记为const。
本文来源:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2049.pdf
For (type-specifier-seq simple-declarator: expression)语句
在语法上等价于
{
typedef decltype(expression) C;
auto&& rng(expression);
for (auto begin(std::For<C>::begin(rng)), end(std::For<C>::end(rng)); begin != end; ++ begin) {
type-specifier-seq simple-declarator(*begin);
statement
}
}
因此,您可以清楚地看到,在您的情况下abc将是std::pair<key_type, value_type >。
对于打印,你可以通过abc访问每个元素。第一,第二