c++的bind使用方法


c++的bind使用方法

除了容器有適配器之外,其實函數也提供了適配器,適配器的特點就是將一個類型改裝成為擁有子集功能的新的類型。其中函數的適配器典型的就是通過std::bind來實現。

std::bind函數定義在頭文件functional中,是一個函數模板,它就像一個函數適配器,接受一個可調用對象(callable object),生成一個新的可調用對象來“適應”原對象的參數列表。一般而言,我們用它可以把一個原本接收N個參數的函數fn,通過綁定一些參數,返回一個接收M個(M可以大於N,但這么做沒什么意義)參數的新函數。同時,使用std::bind函數還可以實現參數順序調整等操作。

可調用 (Callable) 中描述,調用指向非靜態成員函數指針或指向非靜態數據成員指針時,首參數必須是引用或指針(可以包含智能指針,如 std::shared_ptrstd::unique_ptr),指向將訪問其成員的對象。

官方示例

#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 << '\n';
}
 
int g(int n1)
{
    return n1;
}
 
struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    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 << '\n';
 
    // 綁定指向成員函數指針
    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) << '\n';
 
    // 智能指針亦能用於調用被引用對象的成員
    std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
              << f4(std::make_unique<Foo>(foo)) << '\n';
}

輸出:

2 42 1 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10

更多編程資料見公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM