复制一个 std::vector to boost::unordered_map<string, std::vector<foo>>



将记录类型映射到字段值的向量:

unordered_map<string, vector<string>> input_records;
string rec_type {"name"};
vector<string> fields { "field 1", "field 2", "field 3" };

我想把fields复制到input_records[rec_type]。以下不起作用:

_input_records[rec_type].insert(rec_deq.begin(), rec_deq.end()); 

然而,unordered_map的boost文档包含以下内容:

template<typename InputIterator> 
void insert(InputIterator first, InputIterator last);
Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key.
Throws:
When inserting a single element, if an exception is thrown by an operation other than a call to hasher the function has no effect.
Notes:
Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.
Pointers and references to elements are never invalidated.

(写这篇文章时,我意识到InputIterator可能指向一系列键/值对,每一对都要插入Map中。所以,方法不对。)

如何最好地实例化和填充input_record[rec_type]中的矢量?填充后,矢量不会被修改。它和input_record[rec_type] = fields一样简单吗?"移动语义"在这种情况下适用吗?

在标准关联容器中,您推入的是std::对,大多数时候使用std::make_pair()。

#include <vector>
#include <string>
#include <unordered_map>
#include <iostream>
using namespace std;
int main()
{
unordered_map<string, vector<string>> input_records;
string rec_type {"name"};
vector<string> fields { "field 1", "field 2", "field 3" };   
input_records.insert( make_pair( rec_type, fields ) );
for( const auto& text : input_records[rec_type] )
cout << text << 'n';
}

Boost容器也是如此,因为它们是基于标准容器的。

此外,由于C++11还有另一个函数,template(),它允许您创建"就地"的一对,而不必先构建它,然后将它传递给容器:

#include <vector>
#include <string>
#include <unordered_map>
#include <iostream>
using namespace std;
int main()
{
unordered_map<string, vector<string>> input_records;
string rec_type {"name"};
vector<string> fields { "field 1", "field 2", "field 3" };   
input_records.emplace( rec_type, fields );
for( const auto& text : input_records[rec_type] )
cout << text << 'n';
}

根据您传递数据的方式(右值引用、移动等),会有或多或少的副本。然而,适用于所有标准容器的一个简单经验法则是,在必须使用insert()的情况下,您应该尝试使用Template()。

使用input_record[rec_type]的效果正如您所期望的那样。但是,我建议使用find(),因为如果找不到元素,[]操作符会添加一个新元素,而find(()会返回一个迭代器,如果没有找到元素,它将是container.end(),所以你只需将迭代器与end()进行比较,就可以知道元素是否被找到。对于所有标准关联容器和boost容器都是如此。

大多数时候,我使用封装在一个类中的关联容器,该类表示我想要的概念:比如InputRecord类。然后,我提供了一个find函数(或适合域的任何操作名称),它可以根据具体情况执行我想要的操作:有时,如果找不到对象,我希望它抛出异常;有时,当我要查找的对象不在时,我想创建一个新记录;有时,我想返回一个指针;有时我更喜欢返回一个boost::可选。

你最好也这样做:将你的概念封装在一个类下,公开所需的服务,然后在类内使用你想要的任何东西。如果以后需要,您甚至可以轻松地切换到另一个容器,而无需更改接口,只需更改将操作容器的类中的代码即可。

相关内容

最新更新