Как я уже тестировал это в своей IDE VS2015 и читая ошибки компилятора, я заметил, что Ами Тавори избил меня, отвечая на вопрос. Поэтому, возможно, это может дать некоторую информацию или ясность относительно того, что происходит.
В вашем первом поиске, используя lower_bound()
, он компилируется, как указано Ами, и итератор в ваш контейнер возвращается из поиска.
В вашем втором поиске с использованием binary_search()
он не компилируется, и, как заявила Ами, он возвращает только bool, как если бы он был найден или нет. Что касается не компиляции здесь ошибка компилятора из Visual Studio 2015 CE
1>------ Build started: Project: LambdaTemplates, Configuration: Debug Win32 ------
1> LambdaTemplates.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(2709): error C2664: 'bool main::<lambda_79759dd0460f5d162e02d2bb1cee5db7>::operator()(vector_test *,std::string) const': cannot convert argument 1 from 'const std::string' to 'vector_test *'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(2709): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\users\skilz80\documents\visual studio 2015\projects\stackoverflowsolutions\lambdatemplates\lambdatemplates.cpp(46): note: see reference to function template instantiation 'bool std::binary_search<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<vector_test *>>>,std::string,main::<lambda_79759dd0460f5d162e02d2bb1cee5db7>>(_FwdIt,_FwdIt,const _Ty &,_Pr)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<vector_test *>>>,
1> _Ty=std::string,
1> _Pr=main::<lambda_79759dd0460f5d162e02d2bb1cee5db7>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Он говорит, что он не может преобразовать параметр 1 из const std::string
в vector_test*
Так что здесь происходит? Давайте отвлечемся на некоторое время и дадим возможность временно наложить лямбду вне списка параметров предиката вызова функции поиска.Так что часть кода будет выглядеть следующим образом:
auto myLambda = [](vector_test* ptr, std::string name) {
return name < ptr->get_name();
};
auto it = std::binary_search(test.begin(), test.end(), name, myLambda);
if (it)
std::cout << "It is here\n";
else
std::cout << "It is NOT here\n";
Теперь позволяет проверить ошибку компилятора:
1>------ Build started: Project: LambdaTemplates, Configuration: Debug Win32 ------
1> stdafx.cpp
1> LambdaTemplates.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(2709): error C2664: 'bool main::<lambda_79759dd0460f5d162e02d2bb1cee5db7>::operator()(vector_test *,std::string) const': cannot convert argument 1 from 'const std::string' to 'vector_test *'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(2709): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\users\skilz80\documents\visual studio 2015\projects\stackoverflowsolutions\lambdatemplates\lambdatemplates.cpp(45): note: see reference to function template instantiation 'bool std::binary_search<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<vector_test *>>>,std::string,main::<lambda_79759dd0460f5d162e02d2bb1cee5db7>>(_FwdIt,_FwdIt,const _Ty &,_Pr)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<vector_test *>>>,
1> _Ty=std::string,
1> _Pr=main::<lambda_79759dd0460f5d162e02d2bb1cee5db7>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Мы получаем очень похожее сообщение об ошибке. Так что давайте закомментировать строку кода для вызова двоичного поиска и проверки сообщений об ошибках компилятора ...
auto myLambda = [](vector_test* ptr, std::string name) {
return name < ptr->get_name();
};
/*auto it = std::binary_search(test.begin(), test.end(), name, myLambda);
if (it)
std::cout << "It is here\n";
else
std::cout << "It is NOT here\n";
*/
И теперь мы не получаем никаких ошибок компилятора. Таким образом, сам по себе лямбда-это хорошо, однако, что происходит внутри функции binary_search()
заключается в следующем:
Вы передаете его 2 вперед итераторы begin
и end
термин для поиска или значение name
которое является std::string
. Ваши итераторы вперед - векторы vector_test pointers
. Дело не в том, что ваша лямбда не так эффективна, просто функция не может преобразовать из std::string
, являющегося вашим типом данных поискового запроса, в вектор, содержащий указатели на объекты vector_test
, тем самым делая это неправильным типом лямбда для использования или неправильный параметр поиска. Ваш класс объектов vector_test
не предоставляет никаких конструкторов или коэффициентов преобразования или перегруженных операторов для преобразования в std :: string. Также в качестве побочного примечания при использовании binary_search
ваш контейнер должен быть предварительно отсортирован.
Вы не используете ту же самую лямбда: 'return ptr-> get_name() <имя;' не то же самое, что 'return name < ptr-> get_name();', второй ничего не найдет в лексикографически упорядоченном ассортимент. – BeyelerStudios
@ BeyelerStudios, хорошая добыча! Два лямбда точно такие же. Поскольку это не сработало, я изменил порядок. При копировании и вклеивании сюда я не возвращался. Благодаря! – William
@ Якк, по общему признанию, я потратил много времени на редактирование форматирования моего сообщения. Но вы делаете это совершенным. Благодаря! – William