绑定到私有继承的成员函数
Binding to privately inherited member function
我想 std::bind
从私有基 class 到成员函数,在派生 [=31] 中使用 using
声明创建 "public" =].直接调用该函数可以,但似乎绑定或使用成员函数指针无法编译:
#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
,我无法通过外部 Derived
访问 Base
Derived
本身。
这似乎不一致 - 我难道不能交替使用直接调用、绑定函数和函数指针吗?
有没有一种解决方法可以让我绑定到 Derived
对象上的 foo
,最好不要更改 Base
或 Derived
(它们在我的库中不拥有)?
这里的问题是 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
。由于 Base
是 private
,因此通过指向 Base
的指针访问成员的格式不正确。我同意这很不幸("inconsistent" 是个好词)。
您仍然可以创建调用 foo
的函数对象。您只是不能使用指向成员的指针。使用 C++14,如果冗长的话,这会变得简单明了(我在这里假设任意参数,void foo()
只是问题的简化):
auto d_foo = [d](auto&&... args){ return d.foo(std::forward<decltype(args)>(args)...); }
使用 C++11,您必须使用可变参数模板编写类型 operator()
。
我想 std::bind
从私有基 class 到成员函数,在派生 [=31] 中使用 using
声明创建 "public" =].直接调用该函数可以,但似乎绑定或使用成员函数指针无法编译:
#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
,我无法通过外部 Derived
访问 Base
Derived
本身。
这似乎不一致 - 我难道不能交替使用直接调用、绑定函数和函数指针吗?
有没有一种解决方法可以让我绑定到 Derived
对象上的 foo
,最好不要更改 Base
或 Derived
(它们在我的库中不拥有)?
这里的问题是 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
。由于 Base
是 private
,因此通过指向 Base
的指针访问成员的格式不正确。我同意这很不幸("inconsistent" 是个好词)。
您仍然可以创建调用 foo
的函数对象。您只是不能使用指向成员的指针。使用 C++14,如果冗长的话,这会变得简单明了(我在这里假设任意参数,void foo()
只是问题的简化):
auto d_foo = [d](auto&&... args){ return d.foo(std::forward<decltype(args)>(args)...); }
使用 C++11,您必须使用可变参数模板编写类型 operator()
。