【发布时间】:2013-01-23 13:48:55
【问题描述】:
在了解嵌套类是嵌套类的成员并因此可以完全访问嵌套类的成员这一事实之后(至少对于 C++11,请参阅here),我在尝试创建嵌套类模板:
#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;
}
这应该(并且确实)输出:
42 foo
42 not foo
问题
如果#define FORWARD 未注释,即定义了FORWARD,为什么这段代码不能编译?
我得到的错误(来自 gcc 4.7.2)是
main.cpp:11:14: error: ‘enum A::FooBar’ is protected
main.cpp:41:2: error: within this context
从answer 到更早的question 我了解到B 是A 的成员,并且应该可以访问它的(私人)成员(确实如此,它会打印A::i) .那么为什么不能在类外声明中访问A::FooBar 呢?
背景
这显然是一些头和实现分离的其他代码的最小示例。我希望只转发声明嵌套类模板B 以使A 类的接口更具可读性,因为那时我可以将模板类的实现推到头文件的末尾(即行为/setup 可以通过取消注释#define FORWARD 来获得)。
所以是的,这是一个相当化妆品的问题——但我相信这表明我不明白发生了什么,因此我很想了解,但为什么呢? .
【问题讨论】:
标签: c++ templates c++11 nested-class