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

时间:2012-04-22 18:21:00

标签: c++

我试图通过起诉std:find来编写一个搜索函数来获取std :: list中的元素。但我陷入了查找算法的第三个参数,关于这个人How to search for an element in an stl list?我确实重载了运算符==但是它似乎仍然无法使用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;
}

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

2 个答案:

答案 0 :(得分:1)

要使代码正常运行,请从new中移除sort 呼叫。但是,这不会使您的代码更好。

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

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

  1. 不提供此功能。如果Node的用户有一个列表,那么她应该完全有能力自己拨打std::sort
  2. 你不想写包装的锅炉板,你不需要。由于单个参数构造函数采用std::string,您的类可以从string转换(但这应该通过引用获取字符串)。所以你可以写std::find(begin(nodes), end(nodes), "foobar");
  3. 您还可以明确标记构造函数(大部分时间都不需要转换行为),然后只需添加两个免费的operator==(const Node&, const std::string&)operator==(const std::string&, const Node&)
  4. 无论如何。从标题中删除using namespace std;

答案 1 :(得分:1)

您有两个主要问题:

  • 首先,您的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
    

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