2

ネストされたクラスがネストされたクラスのメンバーであり、したがってネストされたクラスのメンバーに完全にアクセスできるという事実を知った後(少なくとも、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

以前の質問への回答から、それはそのメンバーであり、その(プライベート)メンバーにアクセスできる必要があることを学びました(そして、それは印刷されます)。では、なぜクラス外宣言でアクセスできないのでしょうか。BAA::iA::FooBar

バックグラウンド

これは明らかに、ヘッダーと実装が分割されている他のコードの最小限の例です。Bクラスのインターフェイスを読みやすくするために、ネストされたクラステンプレートのみを前方宣言したかったのです。そうすればA、テンプレートクラスの実装をヘッダーファイルの最後にプッシュできたはずです(つまり、取得する動作/セットアップ)。コメントを外すことによって#define FORWARD)。そうです、これはかなり表面的な問題ですが、何が起こっているのか理解していないことを示していると思います。したがって、私は知りたいのですが、なぜですか?

4

1 に答える 1

5

例を次のように単純に減らすことができます。

class A
{
private:
  enum FooBar { foo };

public:
  template< FooBar fb = foo >
  struct B;
};

template< A::FooBar >
struct A::B
{
};

A::B<> a;

これは、 DR 580で明確にされているように合法であり、Clang ++で受け入れられているため、G++はまだその解決策を実装していないようです。

私はこれをGCCPR56248として報告し、 ClangはDR580も完全には実装していないためClangPR15209も報告しました。

于 2013-02-07T23:25:41.150 に答える