jko*_*ian 2 c++ for-loop generator c++11
我有以下代码:
#include "stdafx.h"
#include <map>
#include <string>
#include <iostream>
class MyObject
{
public:
MyObject()
: m_Items{ { 1, "one" },{ 2, "two" },{ 3, "three" } }
{}
RETURNTYPE GetStringIterator() const
{
IMPLEMENTATION
}
private:
std::map<int, std::string> m_Items;
};
int main()
{
MyObject o;
for (auto& s : o.GetStringIterator())
{
std::cout << s;
}
}
Run Code Online (Sandbox Code Playgroud)
什么应该RETURNTYPE和IMPLEMENTATION为了允许任何客户端MyObject(在这种情况下是main()函数)迭代m_Items地图的值,而不复制任何数据?似乎这应该可以使用基于c ++ 11范围的循环和迭代器.但我无法弄清楚如何.
基于范围的迭代可以像这样实现:
class MyObject
{
public:
MyObject()
: m_Items{ { 1, "one" },{ 2, "two" },{ 3, "three" } }
{}
auto begin() { return m_Items.begin(); }
auto begin() const { return m_Items.begin(); }
auto end() { return m_Items.end(); }
auto end() const { return m_Items.end(); }
private:
std::map<int, std::string> m_Items;
};
Run Code Online (Sandbox Code Playgroud)
复制或不复制值取决于代码在调用站点的写入方式:
MyObject a;
for(auto [key,value] : a) {} // copies are made
for(auto & [key,value] : a) {} // no copy
for(auto const & [key,value] : a) {} // no copy
Run Code Online (Sandbox Code Playgroud)
你可以通过删除的非const版本禁用地图值的修改begin和end:
class MyObject
{
public:
MyObject()
: m_Items{ { 1, "one" },{ 2, "two" },{ 3, "three" } }
{}
auto begin() const { return m_Items.begin(); }
auto end() const { return m_Items.end(); }
private:
std::map<int, std::string> m_Items;
};
Run Code Online (Sandbox Code Playgroud)
然后,尝试修改范围for for循环中的值将导致编译错误:
MyObject a;
for(auto & [key,value] : a) {
//value.push_back('a'); // Not OK
}
for(auto & [key,value] : a) {
cout << value; // OK
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果地图是实现细节,则应使用@Barry提出的答案,因为它仅迭代地图的值,而不是关键字.