使用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.*f
当N == 1
,f
是指向类T
成员数据的指针,t1
是types为T
的对象或对types为T
的对象的引用,或者是从类派生的types的对象的引用T
;–
(*t1).*f
当N == 1
,f
是指向类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的成员数据所做的更改。