Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are inner struct/class declarations automatically friend of the nesting class? [duplicate]

Tags:

c++

gcc

c++11

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?

like image 496
πάντα ῥεῖ Avatar asked Dec 05 '25 16:12

πάντα ῥεῖ


1 Answers

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.

like image 126
Lightness Races in Orbit Avatar answered Dec 07 '25 12:12

Lightness Races in Orbit