问题描述
我有以下结构:
struct data {
std::string str;
int num;
int num2;
std::string str2
} data1;
我有一个 std::list<struct data> list
;
我想在 std::list
中添加结构,假设没有这样的结构,使用 std::find_if
和 lambda 函数。
std::list<data>::iterator it = std::find(list.begin(),list.end(),data1);
if (it == list.end()) list.push_back(data1)
你怎么能这样做?
解决方法
您可以迭代列表并将要添加的对象与现有对象进行比较,您可以通过比较所有数据成员来实现,如果它们匹配则对象相等。我建议实现自定义比较运算符,而不是每次需要比较对象时比较数据成员:
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;
}
};
用于 lambda 和 std::find_if()
:
data d{"string1",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);
}
请注意,正如评论部分中的 @Remy pointed out 一样,使用 std::find()
而不是 std::find_if()
可以更轻松地实现这一点:
std::find(list.begin(),d); // comparator implementation also needed
,
要使用 std::find_if
和 lambda:
std::list<data>::iterator it = std::find_if(list.begin(),[&data1](const data& rhs) {
return
data1.str == rhs.str &&
data1.num == rhs.num &&
data1.num2 == rhs.num2 &&
data1.str2 == rhs.str2;
}
);
不过,在这种情况下,我建议定义 data::operator==
并改用 std::find
:
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(),data1);
在 C++20 中,您可以通过默认 operator<=>
(太空飞船操作符)来简化:
默认的 <=>
重载还允许将类型与 <
、<=
、>
和 >=
进行比较。如果 operator<=>
为默认值且根本未声明 operator==
,则 operator==
为隐式默认值。
鉴于此,以下是允许使用所有这些运算符比较 data
的方法:
struct data {
std::string str;
int num;
int num2;
std::string str2;
friend auto operator<=>(const data&,const data&) = default;
};
,
您没有正确声明 std::list
。确保仅指定数据类型。在这种情况下,声明应该是 std::list<data> list;
。
之后,您可以创建 data
类型的对象并使用 std::list
将它们存储在 push_back
中。