0

Aクラス階層で使用されるテンプレート クラスがあり、B::C_#その特殊化メソッドcreate()は次のAとおりです。

template <typename T>
class A
  : public std::map<std::string, double (T::*)() const>
{
  ...

  void create();

  ...
};

template <typename T>
void A<T>::create()
{ assert(false); }

これらのサブクラスの 1 つC_#(たとえばC_0) は、最近まで素晴らしかったです。C_0テンプレートになることを決定するまで、すべてがうまくいきました。彼はこのcreate()専門分野以外はすべてうまくいきました。create()次の方法で特化しようとします。

template<class N1, class N2>
class C_0: public B<N1, N2>
{
  ...
}

...

template<class N1, class N2>
some_namespace::A< some_namespace::C_0<N1, N2> >
  some_namespace::C_0<N1, N2>::A_;

template <>
void some_namespace::A< C_0<N1, N2> >::create() // line 1151
{
  blah_(&C_0<N1, N2>::get_stuff);
}

しかしC_0、これまでの の試みは失敗しました:

C_0.h:1151:45: error: 'N1' was not declared in this scope
C_0.h:1151:49: error: 'N2' was not declared in this scope
C_0.h:1151:51: error: template argument 1 is invalid
C_0.h:1151:51: error: template argument 2 is invalid
C_0.h:1151:53: error: template argument 1 is invalid
C_0.h:1151:63: error: 'create' is not a template function

かわいそうな生き物が彼の問題を克服するのを手伝ってください。

また、specialized でテンプレート メソッドの特殊化を試みましたC_0

namespace some_namespace
{
  class C_0_specialized: public C_0<double_t, size_t>
  {};

  template <>
  void A<C_0_specialized>::create()
  {
    blah_(&C_0_specialized::get_stuff);
  }
}

今回はコンパイルしますが、元のメソッドを呼び出します。void A<T>::create() { assert(false); }

解決

わかりましたので、引数リストを使用して、テンプレート レベルA内でテンプレート クラス全体を部分的に特殊化することになりました。C_0C_0

template<class N1, class N2>
class A< C_0<N1, N2> >
{

  ...

  void create()
  {
    blah_(&C_0<N1, N2>::get_stuff);
  }

  ...

}

その理由は次のとおりです。1) テンプレート メソッドの部分的な特殊化は許可されていないため、単に特殊化することはできずvoid create()、クラスが部分的に特殊化されている場合、すべてのメソッドと変数を特殊化で再定義する必要があります。2)テンプレート引数リストに依存するため、レベルvoid create()内でテンプレート メソッドを明示的に特殊化することはできません。3)のインスタンス(上記のコードのようにインスタンス化されたもの) がテンプレート内で使用され、 atの特殊化が表示されないため、 atテンプレート引数リストが解決されるため、明示的に特殊化できる に特殊化を移動することはできませんでした。C_0AC_0void create()C_0_specializedC_0_specializedAA_C_0A_AC_0レベル。そのため、そのレベルでは のベース バージョンを呼び出していましたvoid create()。また、オーバーヘッドが多すぎるためA_、 のレベルに移動できませんでした。C_0_specialized

クラスAが大きくないのは良いことですが、それでも専門化するだけでよいでしょうvoid create()

このリソースは、テンプレートの明示的な特殊化と部分的な特殊化の違いを説明するのに非常に役立ちます。

4

1 に答える 1

2

N1まず、とN2が型であることをコンパイラに伝えるのを忘れていました

template<class N1, class N2>
void some_namespace::A< C_0<N1, N2> >::create() // line 1151
{
  blah_(&C_0<N1, N2>::get_stuff);
}

A<C_0<N1,N2>>クラスが定義されていないため、これはまだ機能しません。まずそれを宣言します。 : を定義A<T>しましたが、それは一般的なケースであり、メンバーを定義しようとしていない特殊化ではありません。

ところで、次の 3 行はまったく意味がありません。

template<class N1, class N2>
some_namespace::A< some_namespace::C_0<N1, N2> >
  some_namespace::C_0<N1, N2>::A_;
于 2013-10-16T17:25:54.223 に答える