当前位置: 首页 > 知识库问答 >
问题:

尝试从std::vector中提取用户定义的对象时,std::find出现编译错误

都沈浪
2023-03-14

我正在尝试创建一个基本的应用程序,它是建模“粘滞便笺”活动。这将包含添加注释和删除注释的函数。下面是代码。在deleteNote函数中,我正在使用std::find方法在Notes的向量中查找标题,该向量是作为输入参数给出的。std::find API抛出编译错误。下面是代码。

#include <iostream>
#include <vector>
#include <utility>
#include <tuple>
#include <algorithm>

using InitializerTags = std::initializer_list<std::string>;
using TupleObject = std::tuple<std::string, std::string, std::string>;

class Note
{
public:
    TupleObject m_tags;

    Note(std::string title, std::string text, std::string tags){
        std::cout<< "parameterized Constructor"<< std::endl;
        m_tags  =  std::make_tuple(title, text, tags);
    }

    /*Note(const Note& rhs){
        std:: cout << "copy constructor"<< std::endl;
        m_tags = rhs.m_tags;
    }*/

    Note(Note&& rhs){
        std::cout<< "move constructor"<< std::endl;
        m_tags = rhs.m_tags;
    }

    Note& operator=(Note&& rhs){
        std::cout << "move assignment"<< std::endl;
        if(this != &rhs){
            m_tags = rhs.m_tags;
        }
        return *this;
    }

    Note() = delete;
    Note(const Note& rhs) = delete;
    Note& operator=(const Note& rhs) = delete;

    ~Note(){

    }
};

class Storyboard
{
private:
    std::vector <Note> m_notes;
public:

    /*Storyboard(){
        m_notes.reserve(1);
    }*/

    void addNote(std::string title, std::string text, std::string tags)
    {
        std::cout << "inside addNote"<< std::endl;
        m_notes.emplace_back(title, text, tags);
    }

    void deleteNote(std::string title)
    {
        for(auto& x: m_notes){
            if(std::get<0>(x.m_tags) == title){
                m_notes.erase(std::find(m_notes.begin(),m_notes.end(), x));
            }
        }
    }


    void print()
    {
        std::cout << "Inside print"<< std::endl;
        for(auto& x : m_notes){
            std::cout << std::get<0>(x.m_tags)<< " ";
            std::cout << std::get<1>(x.m_tags)<< " ";
            std::cout << std::get<2>(x.m_tags)<< " ";
            std::cout << std::endl;
        }
    }
};

下面是错误。

文件中包含的文件为/usr/include/c++/5/bits/stl_algoBase.h:71:0,文件为/usr/include/c++/5/ios:40,文件为/usr/include/c++/5/ostream:38,文件为/usr/include/c++/5/iostream:39,文件为storyboard.cpp:1:/usr/include/c++/5/bits/predefined_ops.h:在'bool__gnu_cxx::__ops::_iter_equals_val<_value>::operator()::_iter_equals_val]“/usr/include/c++/5/bits/stl_algo.h:3790:28:需要从”_iiter std::find(_iiter,_iiter,const_tp&)“[with_iiter=__gnu_cxx::__normal_iterator ;_tp=Note]“storyboard.cpp:67:73:此处必需/usr/include/c++/5/bits/predefined_ops.h:194:17:错误:”operator==“不匹配(操作数类型为”Note“和”const Note“){return*__it==_m_value;}

我检查了发生错误的文件。

std::find的签名出现问题,该签名是std::find(_iiter,_iiter,const_tp&)

将第三个输入参数作为常量引用,并将其与predefined_ops.h:194中的非常量引用进行比较。

也在想办法解决问题。

如果能帮助我澄清我的理解,我将不胜感激。

共有1个答案

江新
2023-03-14

std::find(m_notes.begin(),m_notes.end(), x)

std::find算法尝试将m_notes中的元素与x进行比较,但您没有提供operator==来进行比较,因此出现错误消息。由于您正在擦除基于标题的元素,您可以这样写:

class Note
{
public:
    //...

    // comparison operator as member function
    bool operator == (const Note& theOther) const {
        // compare titles
        return std::get<0>(m_tags) == std::get<0>(theOther.m_tags);
    }
    //...
};

然后代码会编译,但很可能会崩溃。您使用的是基于范围的for循环,它检查vector::End迭代器,但当调用vector::erase时,它可能会无效。查看如何实现range-for以及如何使用end

现在,您正在遍历vector中的所有元素,如果title与title匹配,则调用find查找要删除的元素。这是矫枉过正的,您可以使用迭代器遍历向量,当标题匹配时,只需调用当前迭代器erase算法,而不需要通过find重新迭代向量:

deleteNote重写为如下所示:

void deleteNote(std::string title)
{
    for (auto it = m_notes.begin(); it != m_notes.end(); )
    {
        if(std::get<0>(it->m_tags) == title)
            it = m_notes.erase(it); // returns the first element past the removed one
        else 
            ++it;
    }
}

如果要在move ctor和move assignment运算符中移动rhs.m_tags;,则需要将rhs.m_tags强制转换为Rreference-m_tags=std::move(Rhs.m_tags);

 类似资料:
  • 考虑代码: Microsoft Visual Studio 2013给出以下错误: C2912:显式特化'CByteArray序列化(const HLVariant 错误C2783:“CByteArray serialize(const std::enable_if::type 错误表明没有

  • 下面的代码显示了我要做的:

  • 错误:无法将类型为“std::_bit_reference&”的非常量lvalue引用绑定到类型为“std::vector::reference”{aka“std::_bit_reference”}的rvalue 因此,它抱怨,因为只有第二个参数是rvalue

  • 我有个问题。为什么我不能编译这个?怎么了? //此代码来自我之前帖子的答案 我有这样的错误: c:\ Program Files(x86)\ Microsoft Visual Studio 8 \ VC \ include \ algorithm(40):错误c 2784:“bool STD::operator = =(const _ Ty C:\Program Files (x86)\Micro

  • 我在std::sort中发现了一个bug,特别是在一些QuickSort的实现中,我不知道问题是否出在一般的算法中。 精华: 当元素小于16时,所有的规范都被替换,因为std::sort使用插入排序。 当有17个或更多的元素时,使用快速排序,并从元素数量的对数限制递归深度,但向量在第一次__introsort_loop迭代时有时间恶化。 当有许多相同的元素时,就会出现向量损坏。用无效迭代器替换有效

  • https://godbolt.org/z/P97MaK 我玩的概念和预期d::is_equality_comparable工作矢量,但它没有。 编译错误在 内部失败,而不是在受概念保护的函数边界处失败。 这是错误还是预期行为?