Нередко начинающие программисты, задающие вопросы на сайте
Stackoverflow, принимают в качестве лучшего ответа ответ с неправильным решением в силу своей недостаточностью знаний и квалификации.
Пример такого поведения можно найти в следующем заданном вопросе начинающего программиста на
Stacloverflow How to find a vector inside a vector Автор вопроса спрашивает, как найти вектор внутри другого вектора. Очевидно, что вопрос сформулирован некорректно. На самом деле автору нужно найти объект типа
struct B внутри вектора типа
std::vector<B>, являющегося членом класса
struct A.
Критерий поиска объектов типа
sstruct B является равенство векторов, объявленных в этих объектах.
Автор признанного лучшим (единственного) ответа решает совершенно другую задачу. Он ищет первых элемент типа
struct B в объекте типа struct A, который содержит любое целочисленное значение, содержащееся в векторе, объявленном в объекте типа
struct B. С этой целью он использует стандартный алгоритм
std::find_first_of.
А как правильно решить поставленную задачу? Имеется два подхода. Первый - это определить оператор равенства для структуры
struct B следующим образом
bool operator ==( const B &left, const B &right )
{
return left.a == right.a;
}
И тогда можно будет использовать стандартный алгоритм
std::find. Например (объявления структур упрощено посредством исключения не используемых полей)
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
struct B
{
std::vector<int> a;
};
bool operator ==( const B &left, const B &right )
{
return left.a == right.a;
}
struct A
{
std::vector<B> a;
};
int main()
{
A s;
s.a.push_back( B { { 10, 29 } } );
s.a.push_back( B { { 50, 69 } } );
B b = { { 10, 29 } };
if ( auto it = std::find( std::begin( s.a ), std::end( s.a ), b ); it != std::end( s.a ) )
{
for ( const auto &item : it->a ) std::cout << item << ' ';
std::cout << '\n';
}
else
{
std::cout << "An object of the type B is not found in the vector s.a\n";
}
}
-
Вывод программы на консоль
10 29
Второй подход состоит в том, чтобы использовать стандартный алгоритм
std::find_if с лямбда-выражением, которое выполняет требуемое сравнение. Например,
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
struct B
{
std::vector<int> a;
};
struct A
{
std::vector<B> a;
};
int main()
{
A s;
s.a.push_back( B { { 10, 29 } } );
s.a.push_back( B { { 50, 69 } } );
B b = { { 10, 29 } };
if ( auto it = std::find_if( std::begin( s.a ), std::end( s.a ), [&]( const B &item ) { return item.a == b.a; } ); it != std::end( s.a ) )
{
for ( const auto &item : it->a ) std::cout << item << ' ';
std::cout << '\n';
}
else
{
std::cout << "An object of the type B is not found in the vector s.a\n";
}
}
В этом случае нет необходимости определять оператор равенства объектов типа
struct B. Вывод программы на консоль будет таким же, как показано выше
10 29