c++ - 绑定(bind)到私有(private)继承的成员函数

标签 c++ stdbind private-inheritance

我想将 std::bind 到私有(private)基类的成员函数,在派生类中使用 using 声明使其“公开”。直接调用函数是可行的,但绑定(bind)或使用成员函数指针似乎无法编译:

#include <functional>

struct Base {
    void foo() { }
};

struct Derived : private Base { 
    using Base::foo;            
};

int main(int, char **)
{
    Derived d;

    // call member function directly:
    // compiles fine
    d.foo();

    // call function object bound to member function:
    // no matching function for call to object of type '__bind<void (Base::*)(), Derived &>'
    std::bind(&Derived::foo, d)();

    // call via pointer to member function:
    // cannot cast 'Derived' to its private base class 'Base'
    (d.*(&Derived::foo))();

    return 0;
}

查看上面的错误消息,问题似乎是 Derived::foo 仍然只是 Base::foo,我无法访问 Base 通过 DerivedDerived 本身之外。

这似乎不一致 - 我应该不能交替使用直接调用、绑定(bind)函数和函数指针吗?

是否有一种解决方法可以让我绑定(bind)到 Derived 对象上的 foo,最好不更改 BaseDerived(哪些在我不拥有的库中)?

最佳答案

这里的问题是 using-declaration 实际做了什么:

struct Derived : private Base { 
    using Base::foo;            
};

这将 Base::foo 带入了 Derived 的公共(public)范围,但它并没有创建一个全新的函数。它等同于写:

struct Derived : private Base {
    void foo() { Base::foo(); }
}

仍然只有 Base::foo()using-declaration 只影响访问规则和重载解析规则。因此 &Derived::foo 确实有 void (Base::*)() 类型(而不是 void (Derived::*)()!),因为那是唯一存在的 foo。由于 Baseprivate,因此通过指向 Base 的指针访问成员是不正确的。我同意这是非常不幸的(“不一致”是个好词)。

您仍然可以创建调用 foo 的函数对象。您只是不能使用指向成员的指针。使用 C++14,即使冗长也变得简单(我在这里假设任意参数,void foo() 只是问题的简化):

auto d_foo = [d](auto&&... args){ return d.foo(std::forward<decltype(args)>(args)...); }

使用 C++11,您必须使用可变参数模板 operator() 编写类型。

关于c++ - 绑定(bind)到私有(private)继承的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36263159/

相关文章:

c++ - 通过复制捕获 Lambda 函数会导致数据损坏

c++ - 在 C++(和 MoveIt API)上将成员函数的 std::bind 作为参数传递时出现问题

C++ 在初始化 std::function 时,我们如何将占位符绑定(bind)到引用/引用参数?

c++ - 需要使用私有(private)继承的设计帮助

c++ - 如何在私有(private)继承中调用父成员?

c++ - 尝试使 C++ (MFC) 代码片段易于重用。有什么选择?

c++ - C++名称查找在这里做什么? (& GCC 对吗?)

c++ - 为什么 auto_ptr 似乎违反了 Visual C++ 上的私有(private)继承?

c++ - PyString_FromStringAndSize 导致段错误

c++ - C++11/14/17 中指向方法回调的指针?