使用std :: bind与成员函数,使用对象指针或不是这个参数?

当使用std::bind绑定一个成员函数时,第一个参数是这个对象的this指针。 然而,它将作为指针传递给对象,而不是。

请参阅以下程序:

 #include <iostream> #include <functional> struct foo { void bar(int v) { std::cout << "foo::bar - " << v << '\n'; } }; int main() { foo my_foo; auto f1 = std::bind(&foo::bar, my_foo, 1); auto f2 = std::bind(&foo::bar, &my_foo, 2); f1(); f2(); } 

铛和海湾合作委员会编译这没有抱怨,结果适用于两个绑定:

 foo :: bar  -  1
 foo :: bar  -  2

我一直试图围绕规范(第20.8.9节),但这是对我来说很不清楚的地方之一。

只有一个是正确的,或者是正确的?

两者都是正确的。 20.8.9.1.2转发到20.8.2来描述你的呼叫bind的要求和效果。 20.8.2是:

20.8.2要求[func.require]

1定义INVOKE (f, t1, t2, ..., tN)如下:

f是一个指向类T的成员函数的指针,并且t1是types为T的对象或对types为T的对象的引用时(t1.*f)(t2, ..., tN)(t1.*f)(t2, ..., tN)一个从T派生的types的对象;

((*t1).*f)(t2, ..., tN)f是指向类T的成员函数的指针时, t1不是前一项中描述的types之一;

t1.*fN == 1f是指向类T成员数据的指针, t1是types为T的对象或对types为T的对象的引用,或者是从类派生的types的对象的引用T ;

(*t1).*fN == 1f是指向类T成员数据的指针,而t1不是前一项中描述的types之一;

– 在所有其他情况下f(t1, t2, ..., tN)

前两个选项允许引用和指针。

这里要注意的重要的一点是,措辞不会限制你的普通指针。 你可以使用一个std::shared_ptr或者其他一些智能指针来保持你的实例在绑定时保持活动状态,它仍然可以在std::bind工作,因为t1被解引用,无论它是什么(当然,这是可能的) 。

添加到正确的答案(这两种forms是允许的)。

我认为这两个绑定选项类似于函数参数声明,可能是“通过值传递”或“通过引用传递”。

f1的情况下(也就是通过值“传递my_foo ”),结果不会“看到”通过绑定点对my_foo所做的任何更改。 这可能是不希望的,特别是如果my_foo发展。 “按价值”绑定有一个额外的(几个)调用复制构造函数的“成本”。

有一个区别。 如rytis提出的,通过值传递不会看到对my_foo所做的更改。 例如,如果my_foo是一个类,通过值传递不会看到对my_foo的成员数据所做的更改。