Harry
Harry

Reputation: 2971

How to use std::find algorithm on a vector of boolean elements

I'm getting this std::_Bit_const_iterator error when trying to find an element in a std::vector<bool> using std::find. Can somebody explain what is it that I'm doing wrong.

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>


int32_t main(int32_t argc, char* argv[]) {
    std::vector<std::vector<bool>> bin_mat;
    bin_mat = { { true, false, false },
                { false, false, true },
                { true, false, false }
              };
      
    for(const auto& row : bin_mat) {
        const std::vector<bool>::iterator row_itr = std::find(row.begin(), row.end(), true);
        std::size_t column_index = std::distance(row_itr, row.begin());
        
        std::cout << column_index << std::endl;
    }
    
    return EXIT_SUCCESS;
}

This is the error I'm getting conversion from ‘std::_Bit_const_iterator’ to non-scalar type ‘const iterator {aka const std::_Bit_iterator}’ requested const std::vector<bool>::iterator row_itr = std::find(row.begin(), row.end(), true);

Upvotes: 0

Views: 948

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122458

You are trying to get a iterator to a const vector. Use a const_iterator and the code is fine:

for(const auto& row : bin_mat) {
    std::vector<bool>::const_iterator row_itr = std::find(row.begin(), row.end(), true);
                      // ^^ ----------- !!!
    // ...
}

You can, but you do not have to make the row_itr itself constant, but you can only get a const_iterator from a const vector (it is const auto& row). You cannot modify the container element via a const_iterator, while a cosnt iterator cannot be assigned a different iterator after initialization. They are different types and you cannot turn a const_iterator to a iterator, that would break const-correctness. Thats basically what the error message is trying to say, leaked implementation details aside it says:

conversion from ‘const_iterator’ to ‘const iterator’ requested

This is similar to pointers to constant ( -> const_iterator) vs constant pointer ( -> const iterator).

Upvotes: 1

Igor Tandetnik
Igor Tandetnik

Reputation: 52471

Since row is a const std::vector<bool>, the return value of std::find is of type std::vector<bool>::const_iterator, and is not convertible to std::vector<bool>::iterator.

Note that const iterator is not at all the same thing as const_iterator - the former means the iterator itself cannot change (e.g. can't be pointed to a different element); the latter means the element pointed to cannot be changed via this iterator.

Just make it auto row_itr = std::find(...) and let the compiler figure out the right type.

Upvotes: 3

Related Questions