Strange behaviour of std::find, returns true when the element is not in the vector

  • A+
Category:Languages

Looks a very straight forward case, a typical use of std::find

for ( auto element : generic->vec() )         LOG << element;      LOG << channel;      if ( !gen->vec().empty() ) {          if(std::find(generic->vec().begin(), generic->vec().end(), channel) != generic->vec().end()){              LOG << "Found";             ;// Found the item         } else {              LOG << "Not Found";             return false;          } } 

Please check the log file

2018-11-08, 09:37:18 [INFO] - [140455150589696] - 1 2018-11-08, 09:37:18 [INFO] - [140455150589696] - 2 2018-11-08, 09:37:18 [INFO] - [140455150589696] - 4 2018-11-08, 09:37:18 [INFO] - [140455150589696] - 12 2018-11-08, 09:37:18 [INFO] - [140455150589696] - 40 2018-11-08, 09:37:18 [INFO] - [140455150589696] - Found 

The vector contains 1,2,4,12 and the incoming value that we want to test if it belongs to the vector is 40. The std::find returns true, that it is found.

The vec() method returns an array of uint64_t elements:

std::vector<uint64_t>  vec() const {   return vec_; } 

When I am creating a local vector, ie

auto tmp = generic->vec(),

the code works.

Where is the bug in my code? I would expect to get "Not found" when checking if 40 belongs to [1,2,4,12].

 


The problem is that your vec function returns the vector by value. That means each call to vec will return a different and distinct vector object. And iterators from different vectors can't be compared to each other.

The simple solution is to return the vector by reference:

std::vector<uint64_t> const&  vec() const { ... } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: