ошибка компиляции при использовании bind2nd

Рейтинг: 0Ответов: 2Опубликовано: 02.02.2023

Начал переносить свой проект на /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, помогите пожалуйста

Ответы

▲ 3

std::bind1st and std::bind2nd были удалены из С++17. std::bind остался, но им не стоит пользоваться (корявый интерфейс - его результат можно вызвать с лишними аргументами, и они просто отбрасываются).

Лучше всего использовать std::bind_front (C++20) или std::bind_back (C++23) или лямбду. (Для вашего случая подходят последние два.)

Но я бы на вашем месте переписал предикаты, чтобы они вызывались так: delete_predicate_by_time(Device.dwTimeGlobal), и возвращали лямбду, захватывающую аргумент.

▲ 0

Можно использовать лямбду или 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);}