【问题标题】:Item’ is not derived from ‘const __gnu_cxx::项目'不是从'const __gnu_cxx::
【发布时间】:2021-11-03 06:40:48
【问题描述】:

我编写了一个程序来从向量中获取对象的引用计数。我将对象存储在列表中,其中有来自向量的计数。我不想按排序顺序存储它们,这就是我使用列表存储的原因。但是在编译时失败并出现错误

"‘Item’ is not derived from ‘const __gnu_cxx::__normal_iterator<_IteratorL, _Container>’". 

我不确定错误。亲爱的朋友,请您回答我以下问题。

  1. 如何解决此错误?
  2. 如何使用任何容器来存储它们及其引用计数,但不是按排序顺序,而是按向量中的到达顺序存储它们? 请使用以下链接查看源文件。
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include<bits/stdc++.h>

using namespace std;

class Item
{
    public:
    int count;
    string name;
    
    Item(){};
    Item(string str, int cnt)
    {
        name = str;
        count = cnt;
    };
};

string func(vector<string>& vec)
{
    list<Item> lst;
    list<Item>:: iterator it;
    for(int i=0; i<vec.size(); i++)
    {
        it = find(lst.begin(), lst.end(), vec[i]);
        if(it != lst.end())
        {
            it->count++;
        }
        else
        {
            lst.push_back({vec[i], 1});
        }
    }
    
    for(it = lst.begin(); it != lst.end(); it++)
    {
        if(it->count == 1)
            return it->name;
    }
    
    return "";
}

int main()
{
    vector <string> vec = {"saint", "catacana", "saint", "ant"};
    cout<<"String is "<<func(vec);

    return 0;
}

【问题讨论】:

  • 请将您的代码缩减为minimal reproducible example
  • 失败的行是it = find(lst.begin(), lst.end(), vec[i]);——您试图在Items 的列表中查找字符串,但编译器不知道如何将字符串与项目进行比较。
  • 这是 GCC 所说的:error: no match for 'operator==' (operand types are 'Item' and 'const std::__cxx11::basic_string&lt;char&gt;')。这就是 Clang 所说的:error: invalid operands to binary expression ('Item' and 'const std::basic_string&lt;char&gt;').
  • Dratenik 发布了正确答案。再加上一些小事情:首先,考虑为构造函数使用初始化列表。其次,如果它什么都不做,则不需要定义默认构造函数。它是默认创建的(有例外,但它们不适用于这种情况)。最后,不要使用全局using namespace std

标签: c++ stl


【解决方案1】:

std::find 失败,因为它试图将 Itemstd::string 进行比较,并且没有定义这样的 == 运算符。

您可以通过将operator==(std::string) 添加到类Item 来解决此问题:

bool operator==(const std::string& name) const {
    return this->name == name;
}

现在这将起作用,但它不是很干净。它将代码添加到类Item 并从其他任何地方调用此函数没有多大意义。它的扩展性也很差,想象你的 Items 有更多的变量,你不想每次搜索新的 Items 属性时都添加一个新函数。

这就是为什么有通用解决方案std::find_if。它接受lamda。这允许您完全指定搜索过程:

for (int i = 0; i < vec.size(); i++)
{
    
    auto search = [&](const Item& item) { //the lambda
        return item.name == vec[i];
    };

    it = find_if(lst.begin(), lst.end(), search); //pass to find_if

  • 阅读here为什么使用命名空间std;被认为是不好的做法,here 为什么要避免&lt;bits/stdc++.h&gt;

【讨论】:

  • 各位朋友,感谢您的宝贵回复。我在测试项目和字符串的相等性时犯了一个愚蠢的错误。
【解决方案2】:

您将find 用于不同的类型,因此得到缺少的运算符编译错误。它可以通过使用 find_if 和 lambda 作为 pred 来修复:

it = find_if(lst.begin(), lst.end(), [&](const Item& item) { return vec[i] == item.name; });

或者添加缺少的operator==

bool operator==(const Item& lhs, const std::string& rhs) {
  return lhs.name == rhs;
}

【讨论】:

    猜你喜欢
    • 2020-11-24
    • 2020-07-14
    • 2020-09-27
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 2021-07-14
    相关资源
    最近更新 更多