如何将私有成员函数作为参数传递
How to pass a private member function as an argument
在ROS中,有一个名为NodeHanle::subscribe(Args...)
的函数:NodeHandle::subscribe。这允许你传递一个 PRIVATE 成员函数作为回调。
但是,当我自己尝试时(使用 std::bind 传递私有成员函数(,我的编译器总是失败并抱怨Foo::foo() is a private member function
。当我Foo::foo
改为公共职能时,一切都恢复正常。
template<typename T>
void getWrapper1(void(T::*fn)(int), T *t) {
return [&](int arg) {
std::cout << "process before function with wrapper" << std::endl;
(t->*fn)(arg);
std::cout << "process after function with wrapper" << std::endl;
};
}
void getWrapper2(std::function<void(int)> fn) {
return [=](int arg) {
std::cout << "process before function with wrapper" << std::endl;
fn(arg);
std::cout << "process after function with wrapper" << std::endl;
}
}
class Foo {
private:
void foo(int a) {
std::cout << __FUNCTION__ << a << std::endl;
}
}
int main(int argc, char** argv) {
Foo foo_inst;
auto func1 = getWrapper1(&Foo::foo, &foo_inst); // fail because foo is private
auto func2 = getWrapper2(std::bind(&Foo::foo, &foo_inst, std::placeholders::_1)); // fail because foo is private
func1(1);
func2(2);
return 0;
}
从这个答案来看,使用std::function
也可以传递私有成员函数。但我尝试的有所不同。
值得一提的是,在getWrapper2
我使用[=]
而不是[&]
,因为使用[&]
可能会导致 seg 错误。为什么它必须是"价值捕获"?
平台: GCC 5.4.0, C++14, Ubuntu16.04
你必须从内部传递它。不能从类外部访问私有函数。甚至没有指向私人东西的指针。私人就是私人。
class Foo {
void foo(int a) {
std::cout << __FUNCTION__ << a << std::endl;
}
public:
auto getWrapper() {
// using a lambda (recommended)
return getWrapper2([this](int a) {
return foo(a);
});
// using a bind (less recommended)
return getWrapper2(std::bind(&Foo::foo, this, std::placeholders::_1));
}
}
为什么它必须是"价值捕获"?
两个包装器都需要值捕获。您的Wrapper1
有未定义的行为。
考虑一下:
// returns a reference to int
auto test(int a) -> int& {
// we return the local variable 'a'
return a;
// a dies when returning
}
同样的事情也会发生在 lambda 上:
auto test(int a) {
// we capture the local variable 'a'
return [&a]{};
// a dies when returning
}
auto l = test(1);
// l contain a captured reference to 'a', which is dead
指针按值传递。指针本身就是一个对象。指针本身有生命周期,可能会死亡。
auto test(int* a) -> int*& {
// we are still returning a reference to local variable 'a'.
return a;
}
而且......你猜对了,std::function
也是这样:
auto test(std::function<void(int)> a) {
// return a lambda capturing a reference to local variable 'a'.
return [&a]{};
}
相关文章:
- 如何在C++中将迭代器作为函数参数传递
- 为什么我不能将引用作为 std::async 的函数参数传递
- 节点插件 API 将数组作为函数参数传递
- 将字符串数组作为函数参数传递
- 如何通过 C++ 中的函数参数传递初始值设定项列表的固定大小的初始值设定项列表?
- 我可以动态创建新地图并作为函数参数传递吗?
- 将任意模板向量作为函数参数C++传递
- 将函数指针作为函数参数传递的目的
- C++:通过函数参数传递的值给出不同的结果
- 当数组大小在C++中未知时,如何在运行时将对字符串数组的引用作为函数参数传递?
- 通过宏将函数参数传递给函数
- C++:访问作为函数参数传递的双指针数组所指向的变量的值
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 将派生类构造函数参数传递给受保护的成员
- 将指向数组的指针作为函数参数传递,这本身就是另一个函数的返回值?
- 如何将二维数组类型字符(字符串)作为函数参数传递?
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- 如何将派生类作为函数参数传递:如果派生类成员不在父类中怎么办
- 如何将变量作为构造函数参数或函数参数传递
- 当数组对象以函数参数传递时,为什么复制构造函数会自称