在c ++ map中添加动态条目

时间:2016-12-08 21:55:15

标签: c++ stl

我知道这可能是一个愚蠢的问题,但我是c ++的新手,我无法找到答案。

我正在使用STL std :: map来维护订阅及其远程服务器IP和PORT的列表。服务器的数量可能因订阅而异。如果订阅的服务器数量为2,那么该订阅将有2个IP地址和2个端口条目。如果1个服务器则1个IP和1个PORT。

std::map<std::string, SubscriptionInfo> sub_list;

struct ServerInfo {
    u_int32_t        ip;
    u_int16_t        port;
};

struct SubscriptionInfo {
    u_int64_t        subscriptionId;
    int              no_of_servers;
    ServerInfo       *remote;
};

我有c struct形式的订阅相关信息,我可以将数据复制到map条目。但是,我不确定如何通过考虑上述内容来添加和删除地图中的条目。是否可以使用地图或有其他替代方案?

1 个答案:

答案 0 :(得分:4)

正如我的评论建议的那样,您应该努力不使用他们不需要的指针,例如ServerInfo *remote;,只需使用std::vector

#include <vector>
#include <map>
#include <string>
#include <cstdint>

struct ServerInfo {
    uint32_t        ip;
    uint16_t        port;
    ServerInfo(uint32_t io_ = 0, uint16_t port_= 0) : 
               ip(ip_), port(_port) {}
};

struct SubscriptionInfo {
    uint64_t        subscriptionId;
    std::vector<ServerInfo> remote;
    SubscriptionInfo(uint64_t val = 0) : subscriptionId(val) {}
};

我更新了SubscriptionInfo以添加一个带有subscriptionId

的构造函数

完成此操作后,可以使用std::map::insert添加现有密钥和订阅信息:

int main()
{
    std::map<std::string, SubscriptionInfo> sub_list;

    // insert an item into the map.  If already existing, return
    // the iterator to the existing item
    auto iter = sub_list.insert({"1",                  // string
                                SubscriptionInfo(1)}). // subscription info
                                first; // item that was inserted, or
                                       // existing item if already in map.

    // push back a new ip and port into the vector.
    (*iter).second.remote.push_back({ 100,18 });  // add IP and port 18
}

基本上我们使用std::map::insert将新项目插入到地图中。 std::map::insert的返回值返回std::pair,其中此对的first是插入项目的迭代器,或者如果已经存在于映射中,则是已经存在的迭代器现有的地图条目。

这就是为什么我们不必检查项目是否存在 - 我们需要做的只是致push_back成员remote,因为我们&#39 ;重新回到insert上的新条目或现有条目的迭代器(请注意,地图本身将其条目存储为std::pair<key_type, value_type>,因此我们希望此对的second得到SubscriptionInfo实例)。

另请注意,我们不需要单独的成员变量来跟踪服务器的数量,因为remote.size()返回向量中的条目数。由于在向量中添加或删除项目时不会手动更新此变量,因此具有诸如no_of_servers之类的无关变量会增加错误发生的可能性。相反,请始终使用std::vector::size()来获取正确的金额。

要删除条目,您只需要key值,并通过调用std::map::erase()函数删除该条目:

    sub_list.erase("1"); // removes key "1" and the data associated with it

编辑:如果您正在使用不符合C ++ 11的编译器,则应对insert的调用进行以下更改:

    typedef std::map<std::string, SubscriptionInfo> MapStringToSub;
    //...
    // insert an item into the map.  If already existing, return
    // the iterator to the existing item
    MapStringToSub::iterator iter = sub_list.insert(std::make_pair("1",  // string
                                SubscriptionInfo(1))). // subscription info
                                first; // item that was inserted, or
                                       // existing item if already in map.

    // push back a new ip and port into the vector.
    (*iter).second.remote.push_back(ServerInfo(100,18));  // add IP and port 18