在C ++ Map中添加动态条目

C_u*_*er5 1 c++ stl

我知道这可能是一个愚蠢的问题,但是我是C ++的新手,所以找不到我的问题的答案。

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

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;
};
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*zie 5

正如我的评论所建议的那样,您应该努力不要在不需要它们的地方使用指针,例如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) {}
};
Run Code Online (Sandbox Code Playgroud)

我更新了,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
}
Run Code Online (Sandbox Code Playgroud)

因此,基本上我们std::map::insert以前是在地图中插入新项目。返回值的std::map::insert返回值为a std::pair,其中first该对的返回是插入项的迭代器,或者如果已存在于地图中,则为已存在的地图条目的迭代器。

这就是为什么我们没有检查,如果该项目存在与否-所有我们需要做的就是调用push_backremote,因为我们要拿回一个迭代器对新的或现有的进入构件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
Run Code Online (Sandbox Code Playgroud)

编辑:如果您使用的是不符合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
Run Code Online (Sandbox Code Playgroud)