在用户定义类型 C++ 的容器上使用 std::find

using std::find on a container of a user-defined type c++

本文关键字:std find 定义 用户 类型 C++      更新时间:2023-10-16

我试图编写一个搜索函数来通过起诉std:find来获取std::list中的元素。但是我卡在查找argorithm的第三个参数中,关于这个家伙如何在stl列表中搜索元素?我确实重载了运算符 == 几乎,但它似乎仍然不适用于 std::find。

这是我的代码:

class Node
{
    string word;
    int count;
    public:
        Node(string _word) :word(_word), count(0) {}
        ~Node() {}
        const string& getWord() const{
            return word;
        }
        bool operator == (const Node& other) const {
            return (this->word.compare(other.word) == 0);
        }
};
const Node &getNode(const list<Node> &nodes, const string &word){
    list<Node>::iterator itr;
    itr = find(nodes.begin(), nodes.end(), new Node(word)); <-- no viable overload '='
    return *itr;
}

我现在对这个问题非常疯狂,请给我一些提示。谢谢

要使代码正常工作,只需从sort中删除new叫。但是,这不会使您的代码变得更好。

您不会检查是否实际找到该元素,而只是取消引用迭代器。如果未找到该元素,则这是未定义的行为。

现在,如何解决这个问题。

  1. 不要提供此功能。如果Node的用户有一个列表,她应该完全有能力自己调用std::sort
  2. 不想写包装的样板,你也不需要。由于单参数构造函数采用string,您的类可以从std::string转换(不过,这应该通过引用获取字符串)。所以你可以写std::find(begin(nodes), end(nodes), "foobar");.
  3. 您还可以将构造函数标记为显式(大多数时候不需要转换行为),然后只需添加两个空闲operator==(const Node&, const std::string&)operator==(const std::string&, const Node&)

无论如何。从标头中删除using namespace std;

您有两个主要问题:

  • 首先,您的find调用是查找指向Node的指针。 new分配内存并返回指针。你想要的是没有new的确切文本。

    itr = find(nodes.begin(), nodes.end(), /*new*/ Node(word));
    

    另请注意,您可以改用word,因为您为构造函数提供了一个字符串参数,因此它将被隐式转换。不过,这通常弊大于利,您最好将构造函数声明为 explicit

    explicit Node(string _word) :word(_word), count(0) {} //need Node("hi")
    

    这将导致将来不那么令人困惑的错误。默认情况下保持显式打开是个好主意。


  • 其次,你的主要问题。您的函数返回一个const string & 。您的迭代器类型为 list<Node>::iterator 。这些不匹配。

    return *itr; //not const
    

    你需要的是这个:

    list<Node>::const_iterator itr; //create a constant iterator instead
    

    其余的可以保持不变,它应该有效(或者至少它对我有用)。