fre*_*low 16 c++ foreach map auto c++11
我试图循环地图的条目,我得到意想不到的副本.这是程序:
#include <iostream>
#include <map>
#include <string>
struct X
{
X()
{
std::cout << "default constructor\n";
}
X(const X&)
{
std::cout << "copy constructor\n";
}
};
int main()
{
std::map<int, X> numbers = {{1, X()}, {2, X()}, {3, X()}};
std::cout << "STARTING LOOP\n";
for (const std::pair<int, X>& p : numbers)
{
}
std::cout << "ENDING LOOP\n";
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
default constructor
copy constructor
default constructor
copy constructor
default constructor
copy constructor
copy constructor
copy constructor
copy constructor
STARTING LOOP
copy constructor
copy constructor
copy constructor
ENDING LOOP
Run Code Online (Sandbox Code Playgroud)
为什么我在循环中得到三个副本?如果我使用类型推断,副本将消失:
for (auto&& p : numbers)
{
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
Mik*_*our 16
值的类型map<K,V>是pair<const K,V>; 所以你的循环需要转换pair<const int,X>为pair<int,X>,复制键和值,以提供对该类型的引用.
使用正确的类型(显式指定或推断auto)将删除副本.
在value_type在std::map<K, V>是不是 std::pair<K, V>,而是std::pair<K const, V>。也就是说,您不能更改元素的关键组成部分。如果编译器发现的请求得到一个std::pair<K, V> const&从std::pair<K const, K> const&它使用的转换构造std::pair<...>,并创建一个合适的临时。
我建议value_type改用以避免任何差异:
for (std::map<int, X>::value_type const& p: numbers)
...
Run Code Online (Sandbox Code Playgroud)
或者,您可以推导类型:
for (auto const& p: number)
...
Run Code Online (Sandbox Code Playgroud)