Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在用户定义的类型为c+的容器上使用std::find+;_C++ - Fatal编程技术网

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

C++ 在用户定义的类型为c+的容器上使用std::find+;,c++,C++,我试图编写一个搜索函数,通过使用std:find来获取std::list中的元素。但是我被困在find算法的第三个参数中,关于这个家伙,我确实重载了操作符==很多,但它似乎仍然不能处理std::find 这是我的代码: class Node { string word; int count; public: Node(string _word) :word(_word), count(0) {} ~Node() {} c

我试图编写一个搜索函数,通过使用std:find来获取std::list中的元素。但是我被困在find算法的第三个参数中,关于这个家伙,我确实重载了操作符==很多,但它似乎仍然不能处理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;
}
类节点
{
字符串字;
整数计数;
公众:
节点(字符串_字):字(_字),计数(0){
~Node(){}
常量字符串&getWord()常量{
返回词;
}
布尔运算符==(常量节点和其他)常量{
返回(this->word.compare(other.word)==0);
}
};
常量节点和getNode(常量列表和节点、常量字符串和单词){
列表::迭代器itr;

itr=find(nodes.begin()、nodes.end()、new Node(word));要使代码正常工作,只需从
排序中删除
new
然而,这并不会使你的代码变得更好

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

现在,如何解决这个问题

  • 不要提供此功能。如果
    节点
    的用户有一个列表,她应该完全能够自己调用
    std::sort
  • 您不想编写包装的锅炉板,也不需要编写。您的类可以从
    std::string
    转换,因为单参数构造函数使用
    string
    (不过这应该通过引用使用字符串)。因此您只需编写
    std::find(begin(nodes),end(nodes),“foobar”);
  • 您还可以将构造函数标记为显式(大多数情况下不需要转换行为),然后只需添加两个免费的
    操作符==(const Node&,const std::string&)
    操作符==(const std::string&,const Node&)

  • 在任何情况下。使用命名空间std;
    从标题中删除

    您有两个主要问题:

    • 首先,您的
      find
      调用正在查找指向
      节点的指针
      new
      分配内存并返回指针。您需要的是不带
      new
      的确切文本

      itr = find(nodes.begin(), nodes.end(), /*new*/ Node(word));
      
      还请注意,您可以只使用
      word
      ,因为您提供了一个带有一个字符串参数的构造函数,因此它将被隐式转换。但这通常弊大于利,最好将构造函数声明为
      显式

      explicit Node(string _word) :word(_word), count(0) {} //need Node("hi")
      
      这将在将来减少令人困惑的错误。默认情况下坚持显式是个好主意


    • 其次是您的主要问题。您的函数返回一个
      常量字符串&
      。您的迭代器类型为
      list::iterator
      。这些类型不匹配

      return *itr; //not const
      
      您需要的是:

      list<Node>::const_iterator itr; //create a constant iterator instead
      
      list::const\u迭代器itr;//改为创建一个常量迭代器
      
      其余的可以保持不变,它应该可以工作(或者至少对我来说是这样)


    您有一个
    节点的列表,但您正在尝试查找指针。删除
    新的
    。删除新的是什么意思。如果喜欢此节点(word);itr=find(nodes.begin(),nodes.end(),Node);现在还没有work@anonymous请检查此项。它有效。您也可以直接传入
    字符串
    。除非您另有需要,否则将构造函数显式化仍然是一个好主意。@chris Non-explicit有时会有所帮助,但它确实很微妙。初学者当然应该避免它。事实上,除非您有充分的理由不这样做(如int->BigInt),避免它会导致不那么奇怪的错误。您能告诉我为什么我们应该从中删除使用名称空间std;吗header@anonymous如果你试图调用某个
    count
    ,它会将许多名称导入当前范围,并导致许多有趣的歧义。不要这样做。