我知道这可能是一个愚蠢的问题,但我是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条目。但是,我不确定如何通过考虑上述内容来添加和删除地图中的条目。是否可以使用地图或有其他替代方案?
答案 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