Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
450 views
in Technique[技术] by (71.8m points)

c++ - C2676 Compiling Error while implementing a list of structs

I am trying to check if there is already an element with same value inside a list of structs so if there isnt I push back to the list a new struct.Consider it like a system with accounts and if there is already an account I dont want to add it on the list again.

Here is my code in main:

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

Here is my code outside of main:

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

};

Here is my code inside a for loop:

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

When I run the code I get a compiler error :

Error C2676 binary '==': 'accounts' does not define this operator or a conversion to a type acceptable to the predefined operator bankacc C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.28.29333includexutility 5440

I have seen other threads and I think I need to do a

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

or something like that but it doesnt work, displaying error:

Error (active) E0135 class "std::list<accounts, std::allocator>" has no member "id"

Any ideas ? :)

question from:https://stackoverflow.com/questions/65829441/c2676-compiling-error-while-implementing-a-list-of-structs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The reason is pretty simple. When you use std::find, what happens under the hood is something like this,

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

Looking at this, you can see that when we pass in your list, the iterator type is std::list<accounts>::iterator but what you check against is accounts::id. There isn't a way to do this.

So what are the options? You have 3,

  1. Create a == operator to the accounts struct.
  2. Just pass in test to test.
  3. Pass in a function to do the compare.

The first is simple, you can copy paste this if you want,

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

Now when std::find calls the == operator, it knows what to do.

The third is simple, use a lambda.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...