I've come over a little discussion today, whether it's necessary to explicitly declare friend access for an inner class/struct. Here's the (replicating sample) code in question:
struct Interface
{
virtual void foo() = 0;
virtual ~Interface() {}
};
class Implementation
{
struct InterfaceImpl : Interface
{
InterfaceImpl(Implementation* impl)
: impl_(impl) {}
virtual void foo()
{
impl_->doFoo(); // << Here's what's in question!!
}
Implementation* impl_;
};
public:
Implementation()
: interfaceImpl_(this) {}
Interface* getInterface() { return &interfaceImpl_; }
private:
InterfaceImpl interfaceImpl_;
void doFoo() {}
};
int main() {
Implementation impl;
return 0;
}
I've been noticing that the code compiles well, where I thought it would be necessary to have a friend struct InterfaceImpl; at the Implementationclass to get it working. So the following setups all work fine: c++11, GCC 4.8.1, GCC 4.3.2.
Is there a c++ (pre-c++11) standard section that confirms this is legal?
They're not friends per se (so your interpretation is subtly wrong), but the effect you've seen is definitely standard-mandated:
[C++11: 11.7/1]:A nested class is a member and as such has the same access rights as any other member. [..]
The example given at this point in the standard is similar to yours.
However, this was not legal in C++03!
[C++03: 11.8/1]:The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules (clause 11) shall be obeyed. [..]
This was considered to be a defect in the standard as early as 1998 (and made into DR #45 in 2001), which may go some way to explaining why you're seeing non-compliant behaviour in GCC, pre-C++11. In that sense, we might see the new C++11 wording as catching up with a long-standing practical reality.
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