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_0
C_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_0
A
C_0
void create()
C_0_specialized
C_0_specialized
A
A_
C_0
A_
A
C_0
レベル。そのため、そのレベルでは のベース バージョンを呼び出していましたvoid create()
。また、オーバーヘッドが多すぎるためA_
、 のレベルに移動できませんでした。C_0_specialized
クラスA
が大きくないのは良いことですが、それでも専門化するだけでよいでしょうvoid create()
。
このリソースは、テンプレートの明示的な特殊化と部分的な特殊化の違いを説明するのに非常に役立ちます。