2

在 C++ 程序中,我有一个 std::list 和 std::map(尽管我实际上使用的是 boost:unordered_map),我想知道一种将列表中的所有元素插入到地图中的优雅方法。我希望密钥是对列表中元素的方法调用的结果。

所以例如我有:

std::list<Message> messages = *another list with elements*;
std::map<std::string, Message> message_map;

我想将列表中的所有元素插入到映射中,键为 message.id(),用于消息中的每条消息。

有没有办法在不循环列表并手动执行的情况下做到这一点?我不能使用 C++11,但出于兴趣,我仍然会对 C++11 解决方案感兴趣。我可以使用提升。

谢谢你。

4

4 回答 4

3

C++11 解决方案:您可以使用std::transformstd::list元素转换为std::map元素:

std::transform(message.begin(), messages.end(),
               std::inserter(message_map, message_map.end()),
               [](const Message& m) { return std::make_pair(m.id(), m); });

通过传递函数指针而不是 lambda 可以使用 C++03 完成等效操作。

于 2013-05-04T21:32:11.013 回答
2

不确定它是否比 for 循环更好,但您可以使用仿函数

struct map_inserter {
   std::map<string,Message>& t_map;
   map_inserter(std::map<string,Message>& t_map) : t_map(t_map) {}
   void operator()(Message& m) {
       t_map.insert(std::pair<string,Message>(m.get_id(),m));
   }
};

你可以像这样使用它

std::map<string,Message> t_map;
std::for_each(vec.begin(), vec.end(), map_inserter(t_map));
于 2013-05-04T21:42:58.370 回答
0

如果您可以获取到 lis 开头和结尾的迭代器,您可以使用 for_each()

于 2013-05-04T21:32:26.487 回答
0

你可以使用accumulate

typedef std::map<std::string, Message> MessageMap;

MessageMap& addIdAndMessage(MessageMap& messageMap, const Message& message) {
    messageMap[message.id()] = message;
    return messageMap;
}

int main() {
    std::list<Message> messages;
    //...
    MessageMap message_map =
        accumulate(messages.begin(), message.end(),
                   MessageMap(),
                   addIdAndMessage);
}
于 2013-05-04T22:01:43.403 回答