I have a list of tuples and need to remove elements from the list, something like this:
enum class test
{
mem1,
mem2,
mem3,
mem4
};
struct A
{
};
int main()
{
std::list<std::tuple<int, test, A>> tuple_list;
// fill list with random objects
for (int i = 0; i < 4; i++)
{
tuple_list.push_back(
std::forward_as_tuple(i, static_cast<test>(i), A()));
}
// now remove it
for (auto& ref : tuple_list)
{
tuple_list.remove(ref); // error C2678
}
return 0;
}
error C2678: binary '==': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion)
How do I remove tuple elements from the list in above example?
EDIT:
I tried following method, it compiles just fine unlike previous example but there is runtime assertion:
int main()
{
list<tuple<int, test, A>> tuple_list;
for (int i = 0; i < 4; i++)
{
tuple_list.push_back(
std::forward_as_tuple(i, static_cast<test>(i), A()));
}
for (auto iter = tuple_list.begin(); iter != tuple_list.end(); iter++)
{
tuple_list.erase(iter);
}
}
Expression: can not increment value initialized list iterator
First off, you don't want to do this . Removing items from a list
(or any container) in the middle of a range-based for
is a recipe for disaster as hidden behind the for
loop are iterators that will be invalidated as soon as the item is removed.
This is the same problem as the second experiment with
for (auto iter = tuple_list.begin(); iter != tuple_list.end(); iter++)
{
tuple_list.erase(iter); // iter rendered invalid.
// That makes iter++ and iter != tuple_list.end()
// totally bogus.
}
This version can be fixed with
for (auto iter = tuple_list.begin(); iter != tuple_list.end(); /* nothing here */)
{
iter = tuple_list.erase(iter); // iter updated here
}
or a
while (! tuple_list.empty())
{
tuple_list.pop_front();
}
Or
tuple_list.clear();
error C2678: binary '==': no operator found which takes a left-hand operand of type 'const _Ty' (or there is no acceptable conversion)
means that one of the parts of the tuple cannot be compared for equality.
struct A
{
};
has no equality operator. Solution is to add one.
struct A
{
};
bool operator==(const A& lhs, const A& rhs)
{
Comparison logic goes here
}
Useful additional reading:
The Erase-Remove idiom can be used to solve similar problems.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.