无法使用自定义运算符 ==() 在 C++ 无序集中找到用户定义的类型
Unable to find a user-defined type in a c++ unordered set with custom operator==()
问题陈述: 遍历对象数组并检查对象是否存在于 unordered_set 中。
目标: 我可以在一个容器中放置数千个对象,以检查它们在另一个容器中的数百万个对象中是否存在。我选择 unordered_set 是因为它不断发现复杂性和迭代向量。我是新手,如果您有任何替代方法,我将不胜感激。
问题: unordered_set 查找没有按预期工作,或者我理解错了!
主线:
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";
}
}
}
块Class过载:
bool Block::operator==(std::unique_ptr<Block>& block) const {
return block->getName() == mName;
}
预期输出:
mod1
mod2
阻止:
#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;
};
一个unordered_set
需要一个散列函数和一个比较函数。您正在为 std::unique_ptr
使用现有的散列和比较函数,这绝对不是您想要的。
我不建议尝试更改 std::unique_ptr<Block>
的行为,因为这会导致其他需要指针正常语义的代码出现混淆。相反,为 Block
添加正常的散列和比较函数,并将自定义的函数传递给 unordered_set
.
的构造函数
您正在尝试比较指针,而不是值。
您需要为 class 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";
}
}
}
问题在于您正在尝试比较不同的指针!
我不知道使用 unique_ptr<> 背后的原因,但这样做实际上是在尝试比较身份,而不是你想要的状态。
所以你明白我的意思了,假设第一个 Block 对象在你记忆中的位置 100。那将是它的身份。所以我们有对象 1,其状态为 "mod1, work",身份为 100。然后我们有对象 2,其身份为 150,但其状态与对象 1 相同,"mod1, work".
向量和 unordered_set 中的所有内容都是指针,因此您有内存位置。将它们插入向量时,比方说,您插入了位置 100。但在 unordered_set 中,您插入了 150。它们具有相同的状态,但 find 方法正在寻找内存位置。
希望我的回答对您有所帮助。如果您在这里发现任何错误或有不同的想法,请告诉我。祝你好运! :)
问题陈述: 遍历对象数组并检查对象是否存在于 unordered_set 中。
目标: 我可以在一个容器中放置数千个对象,以检查它们在另一个容器中的数百万个对象中是否存在。我选择 unordered_set 是因为它不断发现复杂性和迭代向量。我是新手,如果您有任何替代方法,我将不胜感激。
问题: unordered_set 查找没有按预期工作,或者我理解错了!
主线:
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";
}
}
}
块Class过载:
bool Block::operator==(std::unique_ptr<Block>& block) const {
return block->getName() == mName;
}
预期输出:
mod1
mod2
阻止:
#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;
};
一个unordered_set
需要一个散列函数和一个比较函数。您正在为 std::unique_ptr
使用现有的散列和比较函数,这绝对不是您想要的。
我不建议尝试更改 std::unique_ptr<Block>
的行为,因为这会导致其他需要指针正常语义的代码出现混淆。相反,为 Block
添加正常的散列和比较函数,并将自定义的函数传递给 unordered_set
.
您正在尝试比较指针,而不是值。
您需要为 class 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";
}
}
}
问题在于您正在尝试比较不同的指针! 我不知道使用 unique_ptr<> 背后的原因,但这样做实际上是在尝试比较身份,而不是你想要的状态。
所以你明白我的意思了,假设第一个 Block 对象在你记忆中的位置 100。那将是它的身份。所以我们有对象 1,其状态为 "mod1, work",身份为 100。然后我们有对象 2,其身份为 150,但其状态与对象 1 相同,"mod1, work".
向量和 unordered_set 中的所有内容都是指针,因此您有内存位置。将它们插入向量时,比方说,您插入了位置 100。但在 unordered_set 中,您插入了 150。它们具有相同的状态,但 find 方法正在寻找内存位置。
希望我的回答对您有所帮助。如果您在这里发现任何错误或有不同的想法,请告诉我。祝你好运! :)