无法使用自定义运算符 ==() 在 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 方法正在寻找内存位置。

希望我的回答对您有所帮助。如果您在这里发现任何错误或有不同的想法,请告诉我。祝你好运! :)