After learning about the fact that nested classes are members of the nesting class and hence have full access to the nesting class's members (at least for C++11, see here), I ran into an issue when trying to create a nested class template:
#include <iostream>
using namespace std;
// #define FORWARD
class A {
// public: // if FooBar is public, the forward declared version works
protected:
enum class FooBar { // line 11, mentioned in the error message
foo,
bar
};
protected:
#ifdef FORWARD
// forward declaration only
template< FooBar fb = FooBar::foo >
struct B;
#else
// declaration and definition inline
template< FooBar fb = FooBar::foo >
struct B{
void print(){ cout << A::i << (fb==FooBar::foo ? " foo" : " not foo") << endl;};
};
#endif
public:
B<>* f;
B<FooBar::bar>* b;
private:
static const int i = 42;
};
#ifdef FORWARD
// definition of forward declared struct
template< A::FooBar fb>
struct A::B{
void print(){ cout << A::i << (fb==FooBar::foo ? " foo" : " not foo") << endl; };
}; // line 41, mentioned in the error message
#endif
int main(int argc, char **argv)
{
A a;
a.f->print();
a.b->print();
return 0;
}
This should (and does) output:
42 foo
42 not foo
Question
Why doesn't this code compile if #define FORWARD
is un-commented, i.e. FORWARD
is defined?
The error I get (from gcc 4.7.2) is
main.cpp:11:14: error: ‘enum A::FooBar’ is protected
main.cpp:41:2: error: within this context
From an answer to an earlier question I learned that B
is a member of A
and should have access to the (private) members of it (and it does, it prints A::i
). So why isn't A::FooBar
accessible in the out-of-class declaration?
Background
This obviously is a minimal example for some other code where header and implementation are split. I would have liked to only forward declare the nested class template B
in order to make the interface of class A
more readable, as then I could have pushed the template class's implementation to the end of the header file (i.e. the behaviour/setup that one would get by un-commenting the #define FORWARD
).
So yes, this is a rather cosmetic problem to have--but I believe it shows that I don't understand what is going on and hence I am curious to learn about the but why?.