Nested friend class in nested template problem

Discussion in 'C++' started by tonvandenheuvel@gmail.com, Dec 7, 2007.

  1. Guest

    Hi all,

    the following code does not compile in gcc 4.0.2:


    3 class Outer
    4 {
    5 class B;
    6
    7 template<typename T>
    8 class A
    9 {
    10 friend class Outer::B;
    11
    12 public:
    13 A(T t): a(t) { };
    14 A() { };
    15 protected:
    16 T a;
    17 };
    18
    19 class B : public A<int>
    20 {
    21 public:
    22 B(A<int> & a)
    23 {
    24 b = a.a;
    25 }
    26
    27 int b;
    28 };
    29 };

    The error I get is:

    friend.cpp: In constructor 'Outer::B::B(Outer::A<int>&)':
    friend.cpp:16: error: 'int Outer::A<int>::a' is protected
    friend.cpp:24: error: within this context

    Note that when the Outer class is stripped, everything compiles just
    fine. What is the problem here?
     
    , Dec 7, 2007
    #1
    1. Advertising

  2. wrote:
    > Hi all,
    >
    > the following code does not compile in gcc 4.0.2:
    >
    >
    > 3 class Outer
    > 4 {
    > 5 class B;
    > 6
    > 7 template<typename T>
    > 8 class A
    > 9 {
    > 10 friend class Outer::B;
    > 11
    > 12 public:
    > 13 A(T t): a(t) { };
    > 14 A() { };
    > 15 protected:
    > 16 T a;
    > 17 };
    > 18
    > 19 class B : public A<int>
    > 20 {
    > 21 public:
    > 22 B(A<int> & a)
    > 23 {
    > 24 b = a.a;
    > 25 }
    > 26
    > 27 int b;
    > 28 };
    > 29 };


    Please don't post line numbers like you have here. It makes it
    quite difficult to quickly copy-and-paste your code and compile it.
    You can always use *comments* to identify the lines to which the
    compiler is referring in its error messages.

    Thanks.

    >
    > The error I get is:
    >
    > friend.cpp: In constructor 'Outer::B::B(Outer::A<int>&)':
    > friend.cpp:16: error: 'int Outer::A<int>::a' is protected
    > friend.cpp:24: error: within this context
    >
    > Note that when the Outer class is stripped, everything compiles just
    > fine. What is the problem here?


    A buggy compiler?

    Your code compiles OK in Comeau online (4.3.9) or VC++ 2005 SP1.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Dec 7, 2007
    #2
    1. Advertising

  3. On Dec 7, 10:40 pm, wrote:
    > Hi all,
    >
    > the following code does not compile in gcc 4.0.2:
    >
    > 3 class Outer
    > 4 {
    > 5 class B;
    > 6
    > 7 template<typename T>
    > 8 class A
    > 9 {
    > 10 friend class Outer::B;
    > 11
    > 12 public:
    > 13 A(T t): a(t) { };
    > 14 A() { };
    > 15 protected:
    > 16 T a;
    > 17 };
    > 18
    > 19 class B : public A<int>
    > 20 {
    > 21 public:
    > 22 B(A<int> & a)
    > 23 {
    > 24 b = a.a;
    > 25 }
    > 26
    > 27 int b;
    > 28 };
    > 29 };
    >
    > The error I get is:
    >
    > friend.cpp: In constructor 'Outer::B::B(Outer::A<int>&)':
    > friend.cpp:16: error: 'int Outer::A<int>::a' is protected
    > friend.cpp:24: error: within this context
    >
    > Note that when the Outer class is stripped, everything compiles just
    > fine. What is the problem here?


    Note the error message:'int Outer::A<int>::a' is protected.

    B is inherited form A as public inheritance,
    So B can only call A's public and private members.
     
    want.to.be.professer, Dec 7, 2007
    #3
  4. want.to.be.professer wrote:
    > On Dec 7, 10:40 pm, wrote:
    >> Hi all,
    >>
    >> the following code does not compile in gcc 4.0.2:
    >>
    >> 3 class Outer
    >> 4 {
    >> 5 class B;
    >> 6
    >> 7 template<typename T>
    >> 8 class A
    >> 9 {
    >> 10 friend class Outer::B;
    >> 11
    >> 12 public:
    >> 13 A(T t): a(t) { };
    >> 14 A() { };
    >> 15 protected:
    >> 16 T a;
    >> 17 };
    >> 18
    >> 19 class B : public A<int>
    >> 20 {
    >> 21 public:
    >> 22 B(A<int> & a)
    >> 23 {
    >> 24 b = a.a;
    >> 25 }
    >> 26
    >> 27 int b;
    >> 28 };
    >> 29 };
    >>
    >> The error I get is:
    >>
    >> friend.cpp: In constructor 'Outer::B::B(Outer::A<int>&)':
    >> friend.cpp:16: error: 'int Outer::A<int>::a' is protected
    >> friend.cpp:24: error: within this context
    >>
    >> Note that when the Outer class is stripped, everything compiles just
    >> fine. What is the problem here?

    >
    > Note the error message:'int Outer::A<int>::a' is protected.
    >
    > B is inherited form A as public inheritance,
    > So B can only call A's public and private members.


    Actually your post made me think a bit more about this, and perhaps
    I was too fast to judge GCC as buggy...

    Usually the rule is, the derived class is not alloed to access
    *another instance's protected members*, but only its own or of
    another instace of _its own type_. IOW, you should get an error
    in 'foo', but not in 'bar':

    class A {
    protected:
    int a;
    };

    class B : A {
    void foo(A& a) {
    a.a; /// error!
    }

    void bar() {
    this->a; // OK
    }
    };

    However, in this particular case, since A<T> makes 'B' its
    friend, all the rules about protected access are overridden by
    the rules of friendship, which allows access to _all_ members
    regardless of their declared access specifiers.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Dec 7, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ike Naar
    Replies:
    3
    Views:
    1,253
    Jonathan Turkanis
    Feb 26, 2004
  2. Replies:
    2
    Views:
    501
    John Harrison
    Nov 9, 2005
  3. request@no_spam.com
    Replies:
    5
    Views:
    458
  4. A L
    Replies:
    1
    Views:
    530
    Alf P. Steinbach /Usenet
    Aug 25, 2010
  5. Peter
    Replies:
    2
    Views:
    310
    Öö Tiib
    Jun 6, 2013
Loading...

Share This Page