I'm trying to publicly derive a class from a template that will make it inherit from a base class and get access on protected members. But before the template is expanded it doesn't have those rights, so it can't use a Base member as a template parameter:
using Fun = void (*)();
class Base {
protected:
// friend class Derived; // ...need this to eliminate complaint
static void something();
};
template<Fun F>
class Variant : public Base {};
class Derived : public Variant<&Base::something> { // `something()` is protected
public:
void somethingElse() {
something(); // doesn't complain about this `something()`
}
};
int main() {}
The weird bit about this to me was that friending it worked at all. I wondered if I might "sneak Derived in the door" by putting a public virtual inheritance from Base before the Variant:
class Derived : public virtual Base, public Variant<&Base::something>
That didn't help.
Question: is there some other trick for avoiding explicit mention of all derived classes in Base, yet still have access to pick protected members out of it for template parameters?
(Note: Trying this on an older gcc, 4.6.3, looks like even the friending doesn't help in that case. So it seems support for that is somewhat new.)
Stick the offending access into a metafunction. Derive the metafunction class from the base.
template<typename B>
struct something_variant : public B {
typedef Variant< & B::something > type;
};
class Derived : public something_variant<Base>::type {
…
http://coliru.stacked-crooked.com/a/6bca00455bd3daca
Regarding CWG 372, the critical text in the resolution is this:
[A]ccess checking of base-specifiers must be deferred until the entire base-specifier-list has been seen.
This was already accepted in C++11, so it's interesting that your example is rejected. And, plugging the relevant example code from the C++11 standard into recent Clang and GCC demonstrates that they simply did not implement the deferral. It's at least a little unsurprising, since implementation requires some data structure to represent a set of deferred access checks… fairly high effort for a corner case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With