问题陈述:遍历对象数组,并检查对象是否存在于unordered_set中。
目标:我可以在一个容器中容纳数千个对象,以检查它们在另一个容器中的数百万个对象中是否存在。我选择unordered_set是因为它不断发现复杂性和用于迭代的向量。我是新手,如果您有其他替代方法,我将不胜感激。
问题: unordered_set查找未按预期运行,或者我弄错了概念!
Main:
int main() {
std::vector<std::unique_ptr<Block>> vertices;
vertices.push_back(std::make_unique<Block>("mod1", "work"));
vertices.push_back(std::make_unique<Block>("mod2", "work"));
vertices.push_back(std::make_unique<Block>("mod3", "work"));
std::unordered_set<std::unique_ptr<Block>> undefs;
undefs.insert(std::make_unique<Block>("mod1", "work"));
undefs.insert(std::make_unique<Block>("mod2", "work"));
for(auto& vertex : vertices) {
auto search = undefs.find(vertex);
if(search != undefs.end()){
std::cout << "Block: " << vertex->getName() << "\n";
}
}
}
块类重载:
bool Block::operator==(std::unique_ptr<Block>& block) const {
return block->getName() == mName;
}
预期输出:
mod1
mod2
Block:
#pragma once
#include <string>
#include <memory>
using std::string;
class Block {
private:
string mName;
string mLib;
public:
Block(string const& name, string const& lib);
string getName() const;
string getLib() const;
bool operator==(std::unique_ptr<Block>& block) const;
};
您正在尝试比较指针,而不是值。您需要为类Block
指定哈希函数。
例如,如果要使用mName作为键,则代码如下:
class Block {
private:
string mName;
string mLib;
public:
Block(string const& name, string const& lib)
{
mName = name;
mLib = lib;
}
string getName() const {
return mName;
};
string getLib() const {
return mLib;
}
bool operator==(const Block & block) const;
};
template<> struct std::hash<Block> {
std::size_t operator()(const Block & block) const noexcept {
return std::hash<std::string>{}(block.getName());
}
};
bool Block::operator==(const Block & block) const {
return block.getName() == mName;
}
int main() {
std::vector<Block> vertices;
vertices.emplace_back(Block("mod1", "work"));
vertices.emplace_back(Block("mod2", "work"));
vertices.emplace_back(Block("mod3", "work"));
std::unordered_set<Block> undefs;
undefs.emplace(Block("mod1", "work"));
undefs.emplace(Block("mod2", "work"));
for (auto& vertex : vertices) {
auto search = undefs.find(vertex);
if (search != undefs.end()) {
std::cout << "Block: " << vertex.getName() << "\n";
}
}
}
unordered_set
需要散列函数和比较函数。您正在使用std::unique_ptr
的现有哈希和比较功能,这绝对不是您想要的。
我不建议尝试更改std::unique_ptr<Block>
的行为,因为这将导致其他需要普通语义的指针的代码混乱。而是为Block
添加普通的哈希和比较函数,并将自定义的散列和比较函数传递给unordered_set
的构造函数。
问题是您正在尝试比较不同的指针!我不知道使用unique_ptr <>的原因,但是这样做实际上是在尝试比较身份,而不是想要的状态。
所以您可以明白我的意思,假设第一个Block对象在内存中的位置100。那就是它的身份。因此,我们有一个对象1,其状态为“ mod1,工作”,其身份为100。然后,我们有一个对象2,其身份为150,但其状态与对象1相同,即“ mod1,工作”。
向量和unordered_set内部的所有内容都是指针,因此您具有存储位置。当将它们插入向量中时,您插入的位置为100。但是在unordered_set中,您插入的位置为150。它们的状态相同,但是find方法正在查找内存位置。
希望我的回答对您有所帮助。如果您在这里发现任何错误或有不同的想法,请告诉我。祝好运! :)