我知道这可能是一个愚蠢的问题,但是我是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还是有其他替代方法?
正如我的评论所建议的那样,您应该努力不要在不需要它们的地方使用指针,例如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_back上remote,因为我们要拿回一个迭代器对新的或现有的进入构件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)