绑定到私有继承的成员函数

时间:2016-03-28 13:14:31

标签: c++ stdbind private-inheritance

我想std::bind来自私人基类的成员函数,制作"公共"在派生类中使用using - 声明。调用函数直接起作用,但似乎绑定或使用成员函数指针不编译:

#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通过Derived访问Derived本身。

这似乎不一致 - 我是否应该可以交替使用直接调用,绑定函数和函数指针?

是否有一种解决方法可以让我绑定到foo Derived对象上的Base,最好不要更改DerivedFunction PayBack(R As Range) As Variant 'R is a range, assumed to be 1-dimensional 'consisting of negative numbers which 'at some point transition to positive 'returns the cross-over point Dim i As Long, n As Long Dim x As Double, y As Double n = R.Cells.Count x = R.Cells(1).Value If x >= 0 Then PayBack = CVErr(xlErrNA) Exit Function End If 'x < 0 in the following loop: For i = 2 To n y = R.Cells(i).Value If y >= 0 Then x = Abs(x) PayBack = i - y / (x + y) Exit Function End If x = y Next i 'if the code reaches here -- still negative, so return error PayBack = CVErr(xlErrNA) End Function (我不会更改库中的#{1}} 39; t拥有)?

1 个答案:

答案 0 :(得分:4)

这里的问题是 using-declaration 实际上做的事情:

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

这会将Base::foo带入Derived的公共范围,但它不会创建一个全新的功能。 等同于写了:

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()的类型。