4

Linux で GCC 4.8.2 を使用して、ファクトリ メソッド Create() にクラス C のプライベート コンストラクターへのアクセスを許可したいのですが、特殊なフレンドを宣言しようとすると、「エラー: 'Create' はこのスコープで宣言されていませんでした」というメッセージが表示されます。 . B::Create() のすべての型への宣言を開かずにこれを機能させるにはどうすればよいですか?

template <typename T> class A {
 public:
  class B;
  template <typename U> class C;
};

template <typename T>
class A<T>::B {
 public:
  template <typename U> static void Create();
};

template <typename T> template <typename U>
class A<T>::C {
  C() = default;
  friend void B::Create<U>();
};

template <typename T> template <typename U>
void A<T>::B::Create() {
  C<U>{};
}

int main() {
  A<int>::B::Create<char>();
}
4

2 に答える 2

1

コンパイラの欠陥に遭遇したと思います。テンプレートの 1 つのレイヤーのみを使用する次のコードは、g++ 4.8.2 で正常に動作します。

class Foo
{
   public:
      template <typename U> static Foo* Create();
};

template <typename U> class Bar : public Foo
{
   private:
      Bar() = default;

      friend Foo* Foo::Create<U>();
};

template <typename U>
Foo* Foo::Create() {
  return new Bar<U>();
}

ただし、同じコンパイラはコードのコンパイルに失敗します。あなたがすでに試したと思う1つの回避策は、置き換えることです

friend B* B::Create<U>();

template <typename V> 
friend B* B::Create<V>();
于 2015-02-21T08:32:28.317 に答える
1

MSVC++ でコードをテストしたところ、そこでも失敗していました。フレンド宣言にもっと明確な名前を付けるだけで修正できました。完全修飾名はどこにでも指定できることを忘れないでください。

交換したばかり

friend B* B::Create<U>();

friend B* A<T>::B::Create<U>();

MinGW を起動して、実際に期待どおりの動作をするかどうかを確認します。

于 2015-02-21T10:57:38.120 に答える