mem_fn、bind、传递参数时的功能区别

问题描述 投票:0回答:1

如下面的代码和输出所示,可以观察到三个现象:

  1. 对于mem_fn,即代码中的
    f1
    ,无论是传递
    ff
    还是
    &ff
    ,执行后都可以正常修改
    num_
    对象中的
    ff
    值。
  2. 对于bind来说,如果提前绑定了
    ff
    ,则执行后
    num_
    对象中的
    ff
    值不会被修改;如果使用占位符传递
    ff
    或者直接绑定
    &ff
    ,都可以照常修改。
  3. 对于函数来说,如果第一个参数指定为
    Foo
    ,则传递
    ff
    ,执行后不修改
    num_
    对象中的
    ff
    值。

所以我的问题是所有可调用对象都像

INVOKE(f, t1, t2, ..., tN)
一样被调用。为什么会出现以上三个差异?

#include <cstdio>
#include <functional>
#include <iostream>
using namespace std;
struct Foo
{
    Foo(int num) : num_(num) {}
    void print_add(int i)   { num_ += i;}
     int num_;
};

int main()
{

//    cout << "check mem_fn" << endl;
    Foo ff(1);
    auto f1 = std::mem_fn(&Foo::print_add);
    f1(ff, 1);
    cout << "mem_fn ff, num : " << ff.num_ << endl;
    f1(&ff, 1);
    cout << "mem_fn &ff, num : " << ff.num_ << endl;


    auto f2 = std::bind(&Foo::print_add, placeholders::_1, placeholders::_2);
    f2(ff, 1);
    cout << "bind placeholder_1, num : " << ff.num_ << endl;

    std::function<void(int)> f3 = std::bind(&Foo::print_add, ff, placeholders::_1);
    f3(1);
    cout << "bind ff, num : " << ff.num_ << endl;

    std::function<void(int)> f4 = std::bind(&Foo::print_add, &ff, placeholders::_1);
    f4(1);
    cout << "bind &ff, num : " << ff.num_ << endl;

    auto f5 = std::bind(f1, placeholders::_1, placeholders::_2);
    f5(ff, 1);
    cout << "bind_mem_fn ff, num : " << ff.num_ << endl;

    auto f6 = std::bind(f1, placeholders::_1, placeholders::_2);
    f6(&ff, 1);
    cout << "bind_mem_fn &ff, num : " << ff.num_ << endl;


    std::function<void(Foo, int)> f7 = &Foo::print_add;
    f7(ff, 1);
    cout << "function(Foo) num : " << ff.num_ <<endl;

    std::function<void(Foo*, int)> f8 = &Foo::print_add;
    f8(&ff, 1);
    cout << "function(Foo*) num : " << ff.num_ <<endl;

}

输出如下:

mem_fn ff, num : 2
mem_fn &ff, num : 3
bind placeholder_1, num : 4
bind ff, num : 4
bind &ff, num : 5
bind_mem_fn ff, num : 6
bind_mem_fn &ff, num : 7
function(Foo) num : 7
function(Foo*) num : 8
c++ std-function stdbind
1个回答
0
投票

您观察到的是复制

ff
和不复制之间的区别。在所有情况下,可调用对象都会调用成员函数并修改成员。只是有时您看不到
ff
上的修改,因为修改是在
ff
的副本上。

这里:

std::function<void(Foo, int)> f7 = &Foo::print_add;
f7(ff, 1);

已制作副本。还有这里

std::function<void(int)> f3 = std::bind(&Foo::print_add, ff, placeholders::_1);

还有。

© www.soinside.com 2019 - 2024. All rights reserved.