Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I extend a private nested class by a template class?

I have come across a bit of an oddity where it seems a template class can extend a private nested class.

Given the following private nested class:

class A {
private:
  class B {
  protected:
    void doSomething() {
      ...
    }
  };
};

The following does not compile, as expected:

class C : public A::B {
public:
  C() {
    this->doSomething();
  }
};

However, gcc happily seems to accept the following which compiles without a whimper and actually does call through to the method:

template<typename T>
class C : public A::B {
public:
  C() {
    this->doSomething();
  }
};

Does anyone know if this is the expected behaviour when using templates, or have I found an oddity in gcc. I am on version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) so I realise I am a bit out of date. If this is expected behaviour, I would really appreciate an explanation (or a pointer to an explanation) as it isn't what I was expecting and I'd like to know more about it.

Many thanks, Matt

like image 520
Matt__E_ Avatar asked Jun 12 '11 23:06

Matt__E_


1 Answers

That should be a compiler error. The class is not accessible from any class that is not a friend of A, including any instantiation of a class template.

GCC 4.2.1 and 4.6 accept that code

Clang++ rejects it with the error message

error: 'B' is a private member of 'A'
  struct C : A::B {

Comeau rejects the code with a similar message

error: class "A::B" (declared at line 5) is inaccessible
struct C : A::B {
              ^
      detected during instantiation of class "C<T> [with T=int]"
like image 170
David Rodríguez - dribeas Avatar answered Nov 15 '22 06:11

David Rodríguez - dribeas