使用std :: transform转换std :: vector <struct {key; val;} =“”>进入std :: map <key,val =“”>

时间:2017-10-26 07:19:38

标签: c++ c++11 stl stl-algorithm

鉴于以下类型:

struct ComplexLibraryThing { /*lots of fields*/};
typedef std::map<int, ComplexLibraryThing> MyMap;
struct ShadowComplexLibraryThing { /*Shadow of ComplexLibraryThing*/};
struct MyVecType { int a; ShadowComplexLibraryThing b; };
typedef std::vector<MyVecType> MyVector;

我可以这样做序列化(我的序列化库不支持类似地图的类型):

MyVecType map2pair(std::pair<int, ComplexLibraryThing> const &myPair)
{
    MyVecType retVal;
    retVal.a = myPair.first;
    retVal.b = convertForSerialisation(myPair.second);
    return retVal;
}

MyMap myMap = {...};
MyVector myVector;
std::transform(myMap.begin(),
               myMap.end(),
               std::back_inserter(myVector),
               map2pair);

然后我将向量发送到想要重建MyMap的接收器。但是,我找不到像这样执行反序列化的合适<algorithm>模板:

MyMap myNewMap;
for (auto const &entry: myVector)
    myNewMap[entry.a] = convertForDeserialisation(entry.b);

我如何使用<algorithm>来写这个?

(请注意,地图中的ComplexLibraryThing类型无法轻易更改,但我也可以使用ShadowComplexLibraryThing

2 个答案:

答案 0 :(得分:4)

这篇文章展示了如何为std :: map创建一个插入器:

How to insert into std::map? P

迭代的东西的类型必须是std::pair<KeyType, EntryType>(所谓的value_type std::map}。

我认为情况如此:

std::pair<int, ComplexLibraryThing> vec2pair(const MyVecType &myVec)
{
    return std::make_pair(myVec.a,
                          transformForDeserialization(myVec.b));
}

MyVector myVector = {...};
MyMap myMap;
std::transform(myVector.begin(),
               myVector.end(),
               std::inserter(myMap, myMap.end()),
               vec2pair);

答案 1 :(得分:2)

我认为缺少的关键“技巧”是std::inserter。这是一个小小的演示。

#include <algorithm>
#include <iterator>
#include <map>
#include <vector>

struct foo {int a; int b;};

std::vector<foo> GenerateSource() {
  return {};
} 

std::pair<int, int> ConvertFooToMapPair(const foo& f) {
    return {f.a, f.b};
}

int main(int argc, char* argv[]) {
  std::map<int, int> destination;
  std::vector<foo> source = GenerateSource();
  std::transform(
    source.begin(), source.end(),
    std::inserter(destination, destination.end()),
    ConvertFooToMapPair);
}