在map中使用结构体
最近在看Codec2的源码的时候,看到了一个对map使用特殊的地方:
在一个键值对为C2String-ComponentLoader的map中,直接调用emplace+两个String类型的入参,居然能够成功。大致代码如下:
std::map<C2String, ComponentLoader> C2PlatformComponentStore::mComponents;
struct ComponentLoader {
ComponentLoader(std::string libPath) // 有参构造函数
: mLibPath(libPath) {}
private:
std::string mLibPath; ///< library path
};
const char *libPath = "default";
// 奇怪的地方在这里
mComponents.emplace(libPath, libPath);
重点关注mComponents.emplace(libPath, libPath); 。
结合ComponentLoader结构体中的构造函数猜测,std::map如果键值对中有结构体,那么emplace函数就会根据参数列表,找到对应的结构体,初始化该结构体对象。
大胆猜测,小心求证。
写个demo验证一下:
#include <iostream>
#include <map>
#include <string>
struct person {
std::string mName;
person(std::string name) {
mName = name;
std::cout << "person construtor method excuted" << std::endl;
}
};
int main(int argc, const char * argv[]) {
std::map<int, person> pMap;
pMap.emplace(1, "zhangsan");
return 0;
}
输出如下:
person construtor method excuted
验证成功。
结论:
std::map如果键值对中有结构体,那么emplace函数就会根据参数列表,找到对应的结构体,初始化该结构体对象。
另外,既然结构体能够做value,并且有默认调用对应构造函数的操作。结构体是否也能够作为key呢?答案是肯定的。但是做key的结构体,必须是有序的,即必须重载<操作符:
struct person {
std::string mName;
person(std::string name) {
mName = name;
std::cout << "person construtor method excuted: " << mName << std::endl;
}
};
struct person1 {
std::string mName;
int mScore;
person1(std::string name) {
mName = name;
std::cout << "person1 construtor method excuted " << mName << std::endl;
}
bool operator< (const person1 &x) const {
return mScore < x.mScore;
}
};
int main(int argc, const char * argv[]) {
std::map<person1, person> pMap;
pMap.emplace("lisi", "zhangsan");
return 0;
}
输出如下:
person1 construtor method excuted lisi
person construtor method excuted: zhangsan
最后一个问题,如果是类呢?也能实现这样的默认操作么 ?答案是否定的,因为我做实验时,编译报错了。
就这……
|