Reputation: 85
I have a following struct:
struct data {
std::string str;
int num;
int num2;
std::string str2
} data1;
I have a std::list<struct data> list
;
I want to add struct in std::list
, assuming there is no such structure, use std::find_if
and lambda function's.
std::list<data>::iterator it = std::find(list.begin(), list.end(), data1);
if (it == list.end()) list.push_back(data1)
How can you do this?
Upvotes: 1
Views: 1452
Reputation: 23802
You can iterate the list and compare the object you want to add with existing objects, you do it by comparing all data memebers, if they match then the objects are equal. I would advise the implementation a custom comparison operator, instead of comparing data members every time you need to compare objects:
struct data
{
std::string str;
int num;
int num2;
std::string str2;
bool operator==(const data &d)
{
return this->num == d.num && this->str == d.str && this->num2 == d.num2 && d.str2 == this->str2;
}
};
For usage with lambda and std::find_if()
:
data d{"string1", 2, 2, "string2"};
std::list<data>::iterator it = std::find_if(list.begin(), list.end(), [&](const data& dt) {
return d == dt;
});
if(it == list.end())
{
list.push_back(d);
}
Note that, as @Remy pointed out in the comment section, this can be more easily achieved using std::find()
instead of std::find_if()
:
std::find(list.begin(), list.end(), d); // comparator implementation also needed
Upvotes: 2
Reputation: 117308
To use std::find_if
and a lambda:
std::list<data>::iterator it = std::find_if(list.begin(), list.end(),
[&data1](const data& rhs) {
return
data1.str == rhs.str &&
data1.num == rhs.num &&
data1.num2 == rhs.num2 &&
data1.str2 == rhs.str2;
}
);
In this case I would however recommend defining data::operator==
and using std::find
instead:
struct data {
std::string str;
int num;
int num2;
std::string str2;
bool operator==(const data& rhs) const {
return
str == rhs.str &&
num == rhs.num &&
num2 == rhs.num2 &&
str2 == rhs.str2;
}
};
std::list<data>::iterator it = std::find(list.begin(), list.end(), data1);
in C++20, you can simplify this by defaulting operator<=>
(the spaceship operator):
a defaulted
<=>
overload will also allow the type to be compared with<
,<=
,>
, and>=
. Ifoperator<=>
is defaulted andoperator==
is not declared at all, thenoperator==
is implicitly defaulted.
Given that, here's how to allow data
to be compared using all those operators:
struct data {
std::string str;
int num;
int num2;
std::string str2;
friend auto operator<=>(const data&, const data&) = default;
};
Upvotes: 2
Reputation: 438
You did not declare the std::list
properly. Make sure to only specify the data type. In this case, the declaration should have been std::list<data> list;
.
Afterwards you can create objects of type data
and store them inside the std::list
using push_back
.
Upvotes: 0