ошибка компиляции при использовании bind2nd
Начал переносить свой проект на /std:C++17 и возникла ошибка с bind2nd, вот код:
void GlobalFeelTouch::feel_touch_update(Fvector& P, float R)
{
//we ignore P and R arguments, we need just delete evaled denied objects...
xr_vector<Feel::Touch::DenyTouch>::iterator new_end =
std::remove_if(feel_touch_disable.begin(), feel_touch_disable.end(),
std::bind2nd(delete_predicate_by_time(), Device.dwTimeGlobal)); //Ошибка тут
feel_touch_disable.erase(new_end, feel_touch_disable.end());
}
bool GlobalFeelTouch::is_object_denied(CObject const * O)
{
/*Fvector temp_vector;
feel_touch_update(temp_vector, 0.f);*/
if (std::find_if(feel_touch_disable.begin(), feel_touch_disable.end(),
std::bind2nd(objects_ptrs_equal(), O)) == feel_touch_disable.end()) //Ошибка тут
{
return false;
}
return true;
}
Требуется замена bind2nd, помогите пожалуйста
Ответы (2 шт):
Можно использовать лямбду или std::bind. На примере отсюда:
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main () {
int numbers[] = {10,-20,-30,40,-50};
int cx1, cx2, cx3;
cx1 = count_if ( numbers, numbers+5, bind2nd(less<int>(),0) );
cx2 = count_if ( numbers, numbers+5, bind(less<int>(), placeholders::_1, 0) );
cx3 = count_if ( numbers, numbers+5, [](int x){ return less<int>()(x,0);});
cout << "There are " << cx1 << " (bind2nd) " << cx2 << " (bind) " << cx3 << " (lambda) negative elements.\n";
return 0;
}
Результат:
There are 3 (bind2nd) 3 (bind) 3 (lambda) negative elements.
В bind placeholders::_1 означает, какой параметр из переданных в возвращённый bind-ом объект окажется на месте соответствующего аргумента функции:
auto f1 = bind(less<int>(), placeholders::_1, 0);
f1(2); //less<int>()(2, 0)
auto f2 = bind(less<int>(), 0, placeholders::_1);
f2(2); //less<int>()(0, 2)
auto f3 = bind(less<int>(), placeholders::_2, placeholders::_1);
f3(2, 1); //less<int>()(1, 2)
Начиная с С++14 в лямбдах можно использовать auto:
[](auto x){ return less<int>()(x,0);}
std::bind1st and std::bind2nd были удалены из С++17. std::bind остался, но им не стоит пользоваться (корявый интерфейс - его результат можно вызвать с лишними аргументами, и они просто отбрасываются).
Лучше всего использовать std::bind_front (C++20) или std::bind_back (C++23) или лямбду. (Для вашего случая подходят последние два.)
Но я бы на вашем месте переписал предикаты, чтобы они вызывались так: delete_predicate_by_time(Device.dwTimeGlobal), и возвращали лямбду, захватывающую аргумент.