Как использовать заполнители в std :: bind - PullRequest
0 голосов
/ 05 июля 2019

Я даю вам простой фрагмент кода:

#include <functional>
#include <iostream>

using namespace std;


void module2(int x, int y)
{
    cout << "\n "  << __PRETTY_FUNCTION__ << ":\t x = " << x  << "\t y = " << y;
}

void module3(int x, int y, int z)
{
    cout << "\n "  << __PRETTY_FUNCTION__ << ":\t x = " << x  << "\t y = " << y << "\t z = " << z;
}


int main()
{
    using namespace std::placeholders;

    int a = 39;
    int b = 7;
    int c = 3;



    auto func_m2 = bind(&module2, _1, _2);
    func_m2(a, b);                                   //  OK

    auto func_m2_PH = bind(&module2, _2, _1);
    func_m2_PH(b, a);                                   //  OK

    //---------------------------------------------------------

    auto func_m3 = bind(&module3, a, b, c);
    func_m3();                                          //  OK

    cout << "\n With PlaceHolders:";

    auto func_m3_PH_0 = bind(&module3, _1, _2, _3);
    func_m3_PH_0(a, b, c);                              //  OK

    auto func_m3_PH_1 = bind(&module3, _2, _1, _3);
    func_m3_PH_1(b, a, c);                              //  OK

    auto func_m3_PH_2 = bind(&module3, _3, _1, _2);
    func_m3_PH_2(c, a, b);                              //  KO !!!

    auto func_m3_PH_3 = bind(&module3, _3, _2, _1);
    func_m3_PH_3(c, b, a);                              //  OK

    auto func_m3_PH_4 = bind(&module3, _1, _3, _2);
    func_m3_PH_4(a, c, b);                              //  OK

    auto func_m3_PH_5 = bind(&module3, _2, _3, _1);
    func_m3_PH_5(b, c, a);                              //  KO !!!

    return 0;
}

ссылка на колиру

Когда первый аргумент является функцией, которая принимает 2 аргумента, все в порядке: код работает так, как я ожидал.

Однако, когда первый параметр std :: bind является функцией с 3 (или более) аргументами, код перестает работать, как я ожидал (эти случаи отмечены как «KO !!!»)

Но что я ожидаю от std :: bind и его заполнителей?

В этом конкретном случае я ожидаю вывод:

void module3 (int, int, int): x = 39 y = 7 z = 3

каждый раз, когда я вызываю функциональный объект, сгенерированный из

bind(&module3, etc...)  

но, в целом:
Я ожидаю, что параметр, который заменяет заполнитель с именем «_K», будет K-м параметром, передаваемым в базовую функцию (т.е. первый параметр std :: bind).

Что не так? Мое понимание std :: bind или есть ошибка в этом шаблоне функции?

Спасибо за ваше время.

1 Ответ

2 голосов
/ 05 июля 2019

У тебя это задом наперед.Заполнитель _K определяет отображение из K -го аргумента, передаваемого в сгенерированный функтор (результат bind), в положение заполнителя в параметрах связанной функции.Таким образом, размещение _3 в позиции первого аргумента bind означает, что первый аргумент, заданный связанной функции, будет третьим параметром, заданным для сгенерированной функции.

Другие случаисработало, потому что ваша обратная логика оказалась такой же, как и правильная версия.

...