3
template <typename X, typename Y> class A {
    // Use Y::Q, a useful property, not used for specialization.
};
enum Property {P1,P2};
template <Property P> class B {};
class C {};

の通常のテンプレートになるが、特殊化になるAような部分的な特殊化を定義する方法はありますか?A<C, B<P1> >AA<C, B<P2> >

Marcelo に応じて編集: より具体的には、特殊化は B だけでなく、特定のプロパティを示す任意の型で選択する必要があります。たとえば、最初の引数が P2 であるテンプレートです。

目標は、 を使用して のようなものを記述できるようにするYための優れたインターフェイスを提供することです。AA<C, Y<P2,Q> >


テンプレート パラメータをテンプレート テンプレート パラメータに置き換えるのはYいいことですが、それに基づいて部分的に特殊化する方法はありPますか?

意図は次のようなものを書くことです:

template <typename X, template <Property P> typename Y> class A {};
template <typename X> class A<X,template<> Y<P2> > {}; // <-- not valid

In silico に応じて編集: テンプレート テンプレート パラメーターを作成するのはいいことだと言いましたが、実際には、論理的にリンクされたプロパティをグループ化するために使用することですが、1 つに基づいて専門Y化するという、私がやりたかったことの目的を無効にします。それらのサブプロパティの。YA


特殊化に特性を追加してからtemplate <> class B<P2>SFINAE を使用する方法はありAますか? 意図は次のようなものを書くことです:

template <> class B<P2> {
    typedef int IAmP2;
};

// The following is not valid because it's a simple redefinition.
template <typename X, typename Y> class A {
    // Substitution using this template would fail for Y<P1>, and only the 
    // general template would be left for selection.
    typename Y::IAmP2 skipIfNotP2;
};
4

4 に答える 4

4

どういう意味かわかりません。テンプレートテンプレートパラメータは解決策のようですが、どういうわけかそれらは機能しないと言っています。なぜこれをしないのですか?

template <typename X, typename Y> 
class A {
};

template <typename X, template<typename> class Y, typename P> 
class A< X, Y<P> > {
  /* property is P */
};

SFINAEの質問については、はい、それも可能です

template <typename X, typename Y, typename Sfinae = void> 
class A {
};

template <typename X, typename Y> 
class A< X, Y, typename Y::IAmP2 > {
  /* Y is the class having a property */
};

class Sample {
  typedef void IAmP2;
};

それでも私はあなたが何を意味するのか全くわかりません。

于 2010-05-29T12:00:17.110 に答える
0

これは、あなたの望むことですか?(Visual Studio 2005 でテスト済み)

enum Property { P1, P2 }; 

template <Property P> class B {}; 
class C {};

// Other similar types, for the purpose of testing
template <Property P> class AnotherB {};
class AnotherC {};

// Primary template
template <typename X, template<Property P> class Y, Property P> class A
{
public:
    A() { ::printf("Primary template\n"); }
};

// Partial specialization for P2
template <typename X, template<Property P> class Y> class A<X, Y, P2>
{
public:
    A() { ::printf("Partially specialized template\n"); }
};

int main()
{
    // Trying out some combinations
    A<C, B, P1> q;               // prints "Primary template"
    A<C, B, P2> w;               // prints "Partially specialized template"
    A<AnotherC, B, P1> e;        // prints "Primary template"
    A<AnotherC, B, P2> r;        // prints "Partially specialized template"
    A<C, AnotherB, P1> t;        // prints "Primary template"
    A<C, AnotherB, P2> y;        // prints "Partially specialized template"
    A<AnotherC, AnotherB, P1> u; // prints "Primary template"
    A<AnotherC, AnotherB, P2> i; // prints "Partially specialized template"
}

テンプレート テンプレート パラメーターに渡すことができるのは テンプレートのみであるため、部分的な特殊化を試みるとコンパイラ エラーが発生します。template <> class B<P2>テンプレートではなく完全な型であるため、テンプレート テンプレート パラメーターを渡すことはできません。

main()関数の最初の 2 行のコードでは、のtype parameterCに渡す完全な型です。はのテンプレートパラメータに渡すテンプレートであり、そのテンプレートは aを唯一のテンプレート パラメータとして受け入れる必要があります。値 ( または のいずれか) をの非型パラメータに個別に渡します。template の最後の引数を渡すと、コンパイラは特殊化を確認してそれを使用します。それ以外の場合、コンパイラはプライマリ テンプレートを使用します。次の 6 行についても同様のパターンが続きます。AXBAYPropertyPropertyP1P2APP2AA

于 2010-05-29T07:01:17.923 に答える
0

例のコメントに応えて、別の回答を提供しますMatrix

あなたのMatrix例では、これを行うことができます:

enum MatrixOrder { ColumnMajor, RowMajor };

template<MatrixOrder Order> class Dense {};
template<MatrixOrder Order> class Sparse {};

template<typename T, template<MatrixOrder> class Storage, MatrixOrder Order>
class Matrix
{
public:
    Matrix() { ::printf("Primary\n"); }
};

template<typename T, MatrixOrder Order>
class Matrix<T, Dense, Order>
{
public:
    Matrix() { ::printf("Specialized\n"); }
};

int main()
{
    // Trying out some combinations...
    Matrix<double, Dense, ColumnMajor> a;  // Prints "Specialized"
    Matrix<double, Dense, RowMajor> b;     // Prints "Specialized"
    Matrix<double, Sparse, ColumnMajor> c; // Prints "Primary"
    Matrix<double, Sparse, RowMajor> d;    // Prints "Primary"
    Matrix<float, Dense, ColumnMajor> e;   // Prints "Specialized"
    Matrix<float, Dense, RowMajor> f;      // Prints "Specialized"
    Matrix<float, Sparse, ColumnMajor> g;  // Prints "Primary"
    Matrix<float, Sparse, RowMajor> h;     // Prints "Primary"
    return 0;
};

それは私の最後の答えと同様のパターンをとります。現在、採用されているすべてのストレージ スキームDenseは特殊化されます。これが少しでも役に立てば幸いです。:-)

于 2010-05-29T08:03:44.900 に答える
0

テンプレート テンプレート パラメーター (このコンテキストで使用するかどうかはわかりません) がなければ、かなり単純なはずです。

template <> class A<C, B<P2> > { ... };

実際、あまりにも単純です。何かが欠けているに違いないのですが、何が見えません。

于 2010-05-29T06:49:50.337 に答える