实现结构列表时出现 C2676 编译错误

Posted

技术标签:

【中文标题】实现结构列表时出现 C2676 编译错误【英文标题】:C2676 Compiling Error while implementing a list of structs 【发布时间】:2021-04-25 23:49:17 【问题描述】:

我正在尝试检查结构列表中是否已经存在具有相同值的元素,因此如果没有,我会将新结构推回列表。将其视为具有帐户的系统并且是否已经存在帐户我不想再将它添加到列表中。

这是我在 main 中的代码:

accounts test;
test.bal = 0;
test.id = 0;
std::list <accounts> accs;
std::list<accounts>::iterator check;

这是我在 main 之外的代码:

#include <list>
#include <iterator>
#include <algorithm>
struct accounts 
    long id;
    int bal;

;

这是我在 for 循环中的代码:

 check = find(accs.begin(), accs.end(), test.id);
        if (check == accs.end()) 
            accs.push_back(test);
        

运行代码时出现编译器错误:

错误 C2676 二进制“==”:“帐户”未定义此运算符或 转换为预定义可接受的类型 运算符 bankacc C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include\xutility 5440

我看过其他帖子,我想我需要做一个

if(check == accs.id.end())

或类似的东西,但它不起作用,显示错误:

错误(活动)E0135 类“std::list" 没有成员 "id"

有什么想法吗? :)

【问题讨论】:

我想我需要做一个别猜了,编译器会告诉你一个准确的行。 @S.M.让我改进我的问题 if(check == accs.id.end()) 不正确或解决办法。 阅读使用复数名词表示单数事物的代码会变得非常混乱。如果一个类型代表一个帐户,则称它为“帐户”,而不是“帐户”。 @molbdnilo 当我删除 for 循环中的部分时,代码可以工作,是的,我很抱歉你对我忘记更改的变量名是正确的 【参考方案1】:

std::find 采用与容器中要查找的类型相同类型的对象作为最后一个参数。在您的情况下,您应该改用std::find_if

check = find_if(accs.begin(), accs.end(),
    [&test](const auto& ac) 
      return ac.id == test.id;
    );

【讨论】:

非常感谢您的工作。你能解释一下 [&test] 之后它在这里实际做了什么吗?(​​实际上它有效但它没有推动结构)@johnmastroberti 代码使用了 lambda 表达式:https://en.cppreference.com/w/cpp/language/lambda 最后一个参数 find_if 也是一个函数,当满足您要查找的条件时应该返回 true。我在这里用一个 lambda 实现了这一点(从[&amp;test] 到结束大括号的位)。您可以阅读更多关于 here 的信息。我发布的代码仅取代了您对find 的调用。您仍然需要最后三行,如果未找到新帐户,则将其推回。 @johnmastroberti ohhh 好的,非常感谢你。我想 accs 的 size=4456540 是正常的?因为我把它戴在手表上,这就是它给我的尺寸 我想你应该问一个单独的问题。【参考方案2】:

原因很简单。当您使用std::find 时,幕后发生的事情是这样的,

for(iterator i = begin; i != end; i++)
    if(*i == check) return i;

看这个,你可以看到当我们传入你的列表时,迭代器类型是std::list&lt;accounts&gt;::iterator,但你检查的是accounts::id。没有办法做到这一点。

那么有哪些选择呢?你有 3 个,

    accounts 结构创建一个== 运算符。 只需传入test 即可进行测试。 传入一个函数来进行比较。

第一个很简单,你可以复制粘贴这个,

struct accounts 
    long id;
    int bal;
    
    bool operator==(const long& otherID) const  return id == otherID; 
;

现在当std::find 调用== 运算符时,它就知道该做什么了。

第三个很简单,使用 lambda。

check = find(accs.begin(), accs.end(), [&test](const accounts& other) 
      return other.id == test.id; );
if (check == accs.end()) 
    accs.push_back(test);

【讨论】:

所以两个列表都应该是迭代器? 对不起,我错误地发布了错误的答案(完成了一半)。我编辑了它。 第一个错误 Error C2679 binary '==': no operator found which takes a right-hand operand of type 'const _Ty' (or there is no acceptable conversion) bankacc C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include\xutility 5440 和第三个它弹出与以前相同的错误 @TheCodingGuy 我输入了const accounts&amp;,它应该是const long&amp;。抱歉,我修好了。 感谢它修复了错误,但由于某种原因,结构没有被推送并且正在获取数字,它不应该可能是我的错误,谢谢【参考方案3】:

只需重载运算符“==”。在参数中获取你想要的值的类型。

【讨论】:

以上是关于实现结构列表时出现 C2676 编译错误的主要内容,如果未能解决你的问题,请参考以下文章

创建列表时出现分段错误

将 unsigned int 分配给结构中的数组枚举时出现编译错误

在 Flutter 中构建 Streams 时出现编译时错误

将 CSV 文件从 S3 加载到 Snowflake 时出现 SQL 编译错误

分段错误:使用 yosys 编译时出现 11

在析构函数中调用“delete”运算符时出现编译器错误“编译器堆空间不足”