zoukankan      html  css  js  c++  java
  • std::bind

    std::bind

    定义于头文件

    template< class F, class... Args >
    /*unspecified*/ bind( F&& f, Args&&... args );
    
    template< class R, class F, class... Args >
    /*unspecified*/ bind( F&& f, Args&&... args );
    

    函数模板 bind 生成 f 的转发调用包装器。调用此包装器等价于以一些绑定到 args 的参数调用 f .

    The function template bind generates a forwarding call wrapper for f. Calling this wrapper is equivalent to invoking f with some of its arguments bound to args.

    参数

    f - 将绑定参数的可调用对象(函数对象、指向函数指针、到函数引用、指向成员函数指针或指向数据成员指针)
    Callable object (function object, pointer to function, reference to function, pointer to member function, or pointer to data member) that will be bound to some arguments
    args - 要绑定的参数列表,未绑定参数为命名空间 std::placeholders 的占位符 _1, _2, _3... 所替换

    注解

    如可调用 (Callable) 中描述,调用指向非静态成员函数指针或指向非静态数据成员指针时,首参数必须是引用或指针(可以包含智能指针,如 std::shared_ptr 与 std::unique_ptr),指向将访问其成员的对象。

    bind的参数被复制或移动,而且决不按引用传递,除非包装于 std::ref 或 std::cref 。
    The arguments to bind are copied or moved, and are never passed by reference unless wrapped in std::ref or std::cref.

    允许同一 bind 表达式中的多重占位符(例如多个 _1 ),但结果仅若对应参数( u1 )是左值或不可移动右值才良好定义。
    Duplicate placeholders in the same bind expression (multiple _1's for example) are allowed, but the results are only well defined if the corresponding argument (u1) is an lvalue or non-movable rvalue.

    示例

    #include <random>
    #include <iostream>
    #include <memory>
    #include <functional>
     
    void f(int n1, int n2, int n3, const int& n4, int n5)
    {
        std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '
    ';
    }
     
    int g(int n1)
    {
        return n1;
    }
     
    struct Foo {
        void print_sum(int n1, int n2)
        {
            std::cout << n1+n2 << '
    ';
        }
        int data = 10;
    };
     
    int main()
    {
        using namespace std::placeholders;  // 对于 _1, _2, _3...
     
        // 演示参数重排序和按引用传递
        int n = 7;
        // ( _1 与 _2 来自 std::placeholders ,并表示将来会传递给 f1 的参数)
        auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
        n = 10;
        f1(1, 2, 1001); // 1 为 _1 所绑定, 2 为 _2 所绑定,不使用 1001
                        // 进行到 f(2, 42, 1, n, 7) 的调用
     
        // 嵌套 bind 子表达式共享占位符
        auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
        f2(10, 11, 12); // 进行到 f(12, g(12), 12, 4, 5); 的调用
     
        // 常见使用情况:以分布绑定 RNG
        std::default_random_engine e;
        std::uniform_int_distribution<> d(0, 10);
        std::function<int()> rnd = std::bind(d, e); // e 的一个副本存储于 rnd
        for(int n=0; n<10; ++n)
            std::cout << rnd() << ' ';
        std::cout << '
    ';
     
        // 绑定指向成员函数指针
        Foo foo;
        auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
        f3(5);
     
        // 绑定指向数据成员指针
        auto f4 = std::bind(&Foo::data, _1);
        std::cout << f4(foo) << '
    ';
     
        // 智能指针亦能用于调用被引用对象的成员
        std::cout << f4(std::make_shared<Foo>(foo)) << '
    '
                  << f4(std::make_unique<Foo>(foo)) << '
    ';
    }
    
  • 相关阅读:
    tornado源码分析-多进程
    create a cocos2d-x-3.0 project in Xcode
    记录自己的傻逼的错误:找不到或无法载入主类
    MVC5 Entity Framework学习之实现主要的CRUD功能
    Linux中实现多网卡绑定总结
    it码农之心灵鸡汤(一)
    【高级算法】遗传算法解决3SAT问题(C++实现)
    MySQL-分区表-1
    OpenSift源代码编译过程记录
    Android Studio 视图解析
  • 原文地址:https://www.cnblogs.com/yaoyu126/p/12485033.html
Copyright © 2011-2022 走看看