How do I get over the following error about std::vector<bool>?

时间:2017-05-16 09:20:54

标签: c++ vector stl

It seems that vector<bool> doesn't work like usual vectors

auto it = find(flags.rbegin(), flags.rend(), false);

flags.erase(it+1, flags.end());

I want to delete the elements that come (strictly) after the first false from the end. The code (only the 2nd line) produces a long template error, the last line is :

/usr/include/c++/5/bits/stl_bvector.h:1025:5: note: no known conversion for argument 1 from ‘std::reverse_iterator’ to ‘std::vector::const_iterator {aka std::_Bit_const_iterator}’

3 个答案:

答案 0 :(得分:3)

You mix two types of iterator in your erase call, while it expects two compatible iterator that define a range to be deleted.

I guess that is what u want:

 std::vector<bool> flags({false, true, false, true, true});
 auto it = std::find(flags.rbegin(), flags.rend(), false);

 flags.erase(std::next(it.base()), flags.end());

答案 1 :(得分:0)

While std::vector<bool> indeed does not work like normal vectors at all, this particular issue is not related to its idio(syncra)cy.

Reverse iterators and forward iterators on the same range are different types: they are not directly compatible.

Since it is found from rbegin() and rend(), it's a reverse iterator. Note: this also means it + 1 is closer to the beginning of flags than it is.

What you need to do is convert the reverse iterator to its underyling normal iterator:

flags.erase(it.base() + 1, flags.end());

答案 2 :(得分:0)

In your first line you are getting a reverse_iterator because you are using rbegin() and rend() functions in the find(). However, flags.erase() expects a std::vector::const_iterator, and therefore you get the type mismatch in the first argument.

Consider finding the first false value with cbegin() and cend() functions, such as:

auto it = find(flags.cbegin(), flags.cend(), false);

PS: Also consider checking if the value of iterator it is not the last one in the vector to avoid trying to erase something that doesn't exist.