Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Binders

Boost , ,

Binders

Бывают случаи, когда желательно связать простой функтор, функцию, функцию члена или переменную члена для отложенной оценки. Это можно сделать с помощью обязательных условий, предусмотренных ниже. Существуют шаблонные классы:

  1. функция_ptr (функциональный указатель связующего)
  2. functor pointer binder (функторный указатель)
  3. member_function_ptr (связывающее устройство указателя функции члена)
  4. member_var_ptr (связыватель переменных указателей)

Эти классы шаблонов являются специализированными классами ленивых функций для функторов, указателей функций, указателей функций членов и указателей переменных членов соответственно. Это подклассы класса ленивых функций (см. функции). Каждый из них имеет соответствующую перегруженную функцию связывания (x). Каждая функция связывания (x) генерирует подходящий связующий объект.

Пример, приведенная функция foo:

    void foo_(int n) { std::cout << n << std::endl; }

Вот как связана функция foo:

    bind(&foo_)

Это связывает экспрессию с ленивой функцией (см. функции), которая лениво оценивается. Это связывающее выражение также эквивалентно:

    function_ptr<void, int> foo = &foo_;

Параметр шаблона функции_ptr - это тип возврата и аргумента фактической подписи функции, которая должна быть связана слева направо. Примеры:

    void foo_(int);         ---> function_ptr<void, int>
    int bar_(double, int);  ---> function_ptr<int, double, int>

Либо связывание (&foo_) и его эквивалентное foo теперь можно использовать таким же образом, как используется ленивая функция (см. функции):

    bind(&foo_)(arg1)

или

    foo(arg1)

Последнее, конечно, следует за функцией вызова C/C++ и гораздо проще понять. Теперь это полноценная ленивая функция, которую, наконец, можно оценить по другому вызову функции. Второй вызов функции вызовет фактическую функцию foo:

    int i = 4;
    foo(arg1)(i);

Выберите "4".

Связывание функторов и функций участников может быть выполнено аналогичным образом. Вот как связать функтор (например, std::plus):

    bind(std::plus<int>())

или

    functor<std::plus<int> > plus;

Опять же, это полноценные ленивые функции. В этом случае, в отличие от первого примера, следует ожидать 2 аргумента (std::plusтребуется два аргумента lhs и rhs). Один или оба из них могут быть связаны лениво:

    plus(arg1, arg2)        // arg1 + arg2
    plus(100, arg1)         // 100 + arg1
    plus(100, 200)          // 300

Функция связанного члена принимает в качестве первого аргумента указатель или ссылку на объект. Например, учитывая:

    struct xyz { void foo(int) const; };

Функция члена foo xyz может быть связана с:

    bind(&xyz::foo)

или

member_function_ptrxyz_foo = &xyz::foo;

Шаблон параметра Member_function_ptr - это возврат, класс и типы аргументов фактической подписи связанной функции, читаемой слева направо:

    void xyz::foo_(int);            ---> member_function_ptr<void, xyz, int>
    int abc::bar_(double, char);    ---> member_function_ptr<int, abc, double, char>

Обратите внимание, что член_функция_ptr ожидает, что первым аргументом будет указатель или ссылка на объект. И объект (ссылка или указатель), и аргументы могут быть лениво связаны. Примеры:

    xyz obj;
    xyz_foo(arg1, arg2)     // arg1.foo(arg2)
    xyz_foo(obj, arg1)      // obj.foo(arg1)
    xyz_foo(obj, 100)       // obj.foo(100)

Напоминаем, что var(obj) должен использоваться для вызова неконст-членных функций. Например, если xyz был объявлен как:

    struct xyz { void foo(int); };  //  note non-const member function

указатель или ссылка на объект также должны быть неконстными, поскольку лениво связанные аргументы по умолчанию хранятся в виде значения конст (см. класс переменных в примитивах).

    xyz_foo(var(obj), 100)      // obj.foo(100)

arg1..argN уже неявно изменчивы. Нет необходимости заворачивать arg1..argN в вар. Это ошибка, чтобы сделать это:

    var(arg1)   //  ERROR! arg1 is already mutable
    var(arg2)   //  ERROR! arg2 is already mutable

Наконец, переменные могут быть связаны так же, как функции членов. Например, учитывая:

    struct xyz { int v; };

xyz::v может быть связан как:

    bind(&xyz::v)

или

    member_var_ptr<int, xyz> xyz_v = &xyz::v;

Шаблон параметра member_var_ptr - это тип переменной, за которой следует класс:

    int xyz::v; ---> member_var_ptr<int, xyz>

Так же, как член_функция_ptr, член_var_ptr также ожидает, что первым аргументом будет указатель или ссылка на объект. И объект (ссылка или указатель), и аргументы могут быть лениво связаны. Как и связующие функции членов, var(obj) должен использоваться для доступа к переменным, не входящим в состав. Примеры:

    xyz obj;
    xyz_v(arg1)             // arg1.v (const& access)
    xyz_v(obj)              // obj.v  (const& access)
    xyz_v(var(obj))() = 3   // obj.v = 3 (non-const& access)
    xyz_v(arg1)(obj) = 4    // obj.v = 4 (non-const& access)

Еще раз напомним, что связующие являются мономорфными. Этот уровень обеспечивается только для совместимости с существующим кодом, таким как предварительно написанные STL-функторы и устаревшие API. Вместо связывания функций или функторов предпочтительным методом является запись истинных родовых и полиморфных ленивых функций. Однако, поскольку большую часть времени мы имеем дело с адаптацией исходного кода, связующие действительно незаменимы.



Статья Binders раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-24 02:59:39/0.0042641162872314/0