如何将私有成员函数作为参数传递

时间:2019-08-22 18:11:40

标签: c++ functional-programming ros

C preprocessor (CPP) macro中,有一个名为field的函数:ROS。这使您可以将PRIVATE成员函数作为回调传递。

但是,当我自己尝试(使用std :: bind传递私有成员函数)时,我的编译器始终会失败并抱怨NodeHanle::subscribe(Args...)。当我将Foo::foo() is a private member function更改为公共功能时,一切正常。

Foo::foo
NodeHandle::subscribe

,使用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而不是[=],因为使用[&]可能会导致段错误。为什么它必须是“价值捕获”?

平台:GCC 5.4.0,c ++ 14,ubuntu16.04

1 个答案:

答案 0 :(得分:3)

您必须从内部传递它。您不能从类外部访问私有函数。甚至没有指向私人物品的指针。私人就是私人。

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]{};
}