Reputation: 115
I need to find two elements with equal fields. They should be consecutive in the same vector. I need to do it with STL method. I've tried using find or find_if but couldn't do it. Can you give me any hint, please?
My code(some parts of it):
class Sound {
private:
int notePitch, length;
public:
Sound(int notePitch, int length) {
this->notePitch = notePitch;
this->length = length;
}
int getPitch() {
std::cout << "Pitch: " << this->notePitch << " length: " << this->length;
return this->notePitch;
}
};
The actual find function:
std::vector<Sound>::iterator iter = masterpiece.begin();
std::vector<Sound>::iterator iterEnd = masterpiece.end();
std::vector<Sound>::iterator it = find_if(iter, iterEnd, [](auto prev, auto next) -> bool {
return prev.getPitch() == next.getPitch();
});
The error I get is this:
c2678 binary '==' no operator found which takes a left-hand operand of type
Upvotes: 0
Views: 1463
Reputation: 311048
The standard algorithm std::find_if
does not accept a binary predicate.
You can use the standard algorithm std::adjacent_find
with a lambda expression.
The member function getPitch
should be declared with the qualifier const
. In this case you can use the function for constant objects (for example when an object of the type Sound or a vector of objects Sound is passed to a function that accepts a constant reference)
Here is a demonstrative program
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
class Sound {
private:
int notePitch, length;
public:
Sound(int notePitch, int length) {
this->notePitch = notePitch;
this->length = length;
}
int getPitch() const {
// std::cout << "Pitch: " << this->notePitch << " length: " << this->length;
return this->notePitch;
}
};
int main( void )
{
std::vector<Sound> masterpiece = { { 1, 2 }, { 2, 3 }, { 2, 4 }, { 3, 5 } };
auto it = std::adjacent_find( std::begin( masterpiece ), std::end( masterpiece ),
[]( const Sound &a, const Sound &b )
{
return a.getPitch() == b.getPitch();
} );
if ( it != std::end( masterpiece ) )
{
std::cout << "Two adjacent elements are found at position "
<< std::distance( std::begin( masterpiece ), it )
<< '\n';
}
else
{
std::cout << "Two adjacent elements are found\n";
}
}
The program output is
Two adjacent elements are found at position 1
You can the parameters of the lambda expression to write using auto
[]( const auto &a, const auto &b )
{
return a.getPitch() == b.getPitch();
}
But in any case it is better to declare them as having a const referenced type because in this case neither temporary objects will be created and the lambda expression guarantees that it does not change its arguments.
Upvotes: 1
Reputation: 1033
Use adjacent_find in place of find_if. Your code should work.
std::vector<Sound>::iterator it = adjacent_find (iter, iterEnd, [](auto prev, auto next) -> bool {
return prev.getPitch() == next.getPitch();
Upvotes: 1