ネストされたクラスがネストされたクラスのメンバーであり、したがってネストされたクラスのメンバーに完全にアクセスできるという事実を知った後(少なくとも、C ++ 11については、ここを参照)、ネストされたクラステンプレートを作成しようとしたときに問題が発生しました:
#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
以前の質問への回答から、それはそのメンバーであり、その(プライベート)メンバーにアクセスできる必要があることを学びました(そして、それは印刷されます)。では、なぜクラス外宣言でアクセスできないのでしょうか。B
A
A::i
A::FooBar
バックグラウンド
これは明らかに、ヘッダーと実装が分割されている他のコードの最小限の例です。B
クラスのインターフェイスを読みやすくするために、ネストされたクラステンプレートのみを前方宣言したかったのです。そうすればA
、テンプレートクラスの実装をヘッダーファイルの最後にプッシュできたはずです(つまり、取得する動作/セットアップ)。コメントを外すことによって#define FORWARD
)。そうです、これはかなり表面的な問題ですが、何が起こっているのか理解していないことを示していると思います。したがって、私は知りたいのですが、なぜですか?。