1

私はジェネリックMatrixクラスを持っています。値の行列を扱うときのために、SSE に最適化された行列乗算関数がありFloatます。現在、私の方法論には、いくつかのチェックを含む行列乗算による行列を行う「doSSE_mulMM」という名前の関数が含まれていますが、関連するのはMatrix<Float>(コードで SSE 機能のチェックを行い、以下に移動するため、部分的に存在します)。 SSE が利用できない場合の効率的な乗算)。

ビルド サーバーが実行している GCC のバージョンでは、次のエラーが発生します。

error: specialization of ‘MTI::Matrix<float>& MTI::Matrix<BT>::doSSE_MulMM(const MTI::Matrix<float>&, const MTI::Matrix<float>&, bool) [with BT = float]’ after instantiation

同じコードは、Visual Studio と、Linux ホスト上の古いバージョンの GCC で正常にコンパイルされます。

完全なコードを提供することはできませんが、これらは関数のシグネチャです。

Matrix.h

template <class BT> 
class Matrix {
    ....
    Matrix<Float>&  doSSE_MulMM      (const Matrix<Float>& mat1, const Matrix<Float>& mat2, bool softmax);
    ....
}

マトリックス.cpp

template <> 
Matrix<Float>&  Matrix<Float>::doSSE_MulMM (const Matrix<Float>& mat1, 
                                 const Matrix<Float>& mat2,
                                 bool softmax) {
    ....
}

関数doSSE_MulMMonly は実際には Float 行列に対して意味がありますが、Matrix のプライベート データ メンバーで動作するため、メンバー関数にすることを強くお勧めします。Matrix クラスの 1 つの特殊化にのみ存在するように関数を特殊化する良い方法はありますか? 他のデータ型に対して例外を発生させる一般的なバージョンを導入できると思いますが、それは面倒です。

4

4 に答える 4

1

関数を 1 つの型だけに存在させる簡単な方法は CRTP であり、そこで特化します。CRTP を使用すると、関数を実装する時点で完全な型にアクセスできます。特殊化により、関数を特定の型に対してのみ存在させることができます。

おもちゃの例を次に示します。

template<typename D, typename T>
struct foo_for_float {};
template<typename D>
struct foo_for_float<D, float> {
  D* self() {
    static_assert( std::is_base< foo_for_float<D, float>, D >::value, "CRTP error" );
    return static_cast<D*>(this);
  }
  D const* self() const {
    static_assert( std::is_base< foo_for_float<D, float>, D >::value, "CRTP error" );
    return static_cast<D const*>(this);
  }
  void foo() { // const if you want to
    // use self() in this method instead of this
  }
};
// The usual CRTP magic "pass my own type to my parent":
template<typename T>
struct test : foo_for_float<test<T>, T> {
  void bar() {}
}
int main() {
  test<int> a;
  test<float> b;
  a.bar(); // valid
  b.bar(); // valid
  b.foo(); // valid
  a.foo(); // not found
}
于 2013-08-30T14:28:08.577 に答える
0

そのためには、完全なテンプレート Matrix を特殊化する必要があります。クラス テンプレートの 1 つのメンバー関数だけを特殊化することはできません。その後、プライベート メンバーを好きなだけ追加できます。スペシャライゼーションでテンプレート コントラクトを満たすように注意している場合、Matrix の汎用アルゴリズムは違いを認識できません。

于 2013-08-30T13:35:44.297 に答える