Q#1) 下面的结构不想被复制并给出编译错误 - 为什么以及如何处理它?</p>
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct person
{
person(string n)
:name(n)
{}
string name;
};
int main()
{
map<string, person> my_map;
my_map["one"] = person("Tom");
return 0;
}
Q#2) 我们可以通过省略结构构造函数“person(const string& n)”并一一分配结构值来避免上述问题:
#include <iostream>
#include <string>
#include <map>
using namespace std;
struct person
{
string name;
};
int main()
{
map<string, person> my_map;
person p;
p.name = "Tom";
my_map["one"] = p;
return 0;
}
所以,假设我是这样做的,在 map 中存储了很多人之后,我想检查某个特定的人是否存在于 map 中。据我所知,正确的做法是:
if(my_map.find("one") == my_map.end()) { //it doesn't exist in my_map }
else {//it exists}
但据我了解,这将一张一张地遍历整个 map ,不是吗?如果是,那么可以这样做吗:
using namespace std;
struct person
{
string name;
string identifier; // <--
};
int main()
{
map<string, person> my_map;
person p;
p.name = "Tom";
p.identifier = "something"; // <--
my_map["one"] = p;
if(my_map["unknown"].identifier == "something") // <--
cout << "Found" << endl;
else
cout << "Not found" << endl;
return 0;
}
通过这样做,我们避免了迭代,并且内存中的垃圾与我们的标识符匹配的可能性是……我猜很小,特别是如果我们使用一些散列。 那么这样做可以(安全)吗?
最佳答案
1) 由于以下表达式,第一个示例中的代码无法编译:
my_map["one"]
my_map["one"]
构造一个 std::string
来自 "one"
, 并将其传递给 std::map::operator[] . map::operator[]
确保将值映射到提供的键(如果键尚未与值关联,则通过将键与默认构造的值关联)并返回对该值的引用。
这不会编译,因为 person
没有默认构造函数(“默认构造函数”是不带参数的构造函数)。
有几种方法可以解决这个问题。
一种方法是您采用的方法 - 删除构造函数。它之所以有效,是因为如果您不提供任何构造函数,则会隐式定义一个默认构造函数。
另一种方法是为 person
显式定义默认构造函数:
struct person
{
person():name(){} //or person()=default; if your compiler supports this
person(string n)
:name(n)
{}
string name;
};
另一种方法是不使用 operator[]
完全没有,而是使用 map::insert ,如下:
auto pair(my_map.insert(std::make_pair(std::string("one"),person("Tom"))));
if (!pair.second) {
*pair.first = person("Tom");
}
2) 在 map 中查找元素的正确方法是(如您所说)使用:
if(my_map.find("one") == my_map.end()) {/*it doesn't exist in my_map*/}
else {/*it exists*/}
这不会检查 map 中的每个元素 - 事实上它可能只检查 O(log(map.size()))
元素。
您的担心完全没有根据,这是在 map 中查找元素的正确方法,但是您继续使用的方式表明您对 operator[]
的内容存在严重误解。
您问“如果 my_map["unknown"].identifier == "something"
在 map 中不存在,"unknown"
返回真值的概率是多少?”。
这个问题的答案是没有任何机会返回 true,因为如果键 std::string("unknown")
没有值存在于 map 中,则operator[]
会联想std::string("unknown")
默认构造 person
,等等 identifier
将是一个空字符串。
关于c++ - 在 map 中存储结构;检查 map 中是否存在结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10309828/