0

単純なテンプレート マトリックス クラスを作成しました。getMat 関数は元のサブ マトリックスを異なるサイズで返す必要があるため、次のようにコーディングしました。

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> Matrix<T,m,n,_Prd>::getMat(const size_t& ulrow, const size_t& ulcol ) const 
{
    assert(_m+ulcol <= m && _n+ulrow <= n) ;
    T temp[_m*_n] ;
    for (size_t j = 0 ; j < _m ; ++j)
        for (size_t i = 0 ; i < _n ; ++i)
            temp[j*_n+i] = data[(ulrow + j) * n + ulcol+i] ;
    return Matrix<T,_m,_n,_Prd>(temp) ;
}

次に、次のように呼び出します。

Matrix<double, 4,4> testmat2(100.0) ;
Matrix<double,2,2> testmat4 =  testmat2.getMat(0,0) ;

そして、次のようなエラーが表示されます。

main.cpp:127: error: no matching function for call to ‘Matrix<double, 4ul, 4ul, std::equal_to<double> >::getMat(size_t, size_t)’

だから私の質問は、なぜコンパイラがこの getMat 関数を検出しないのですか?

アップデート:

私はこの方法でコードを試しましたが、うまくいきます:

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
void Matrix<T,m,n,_Prd>::getMat(Matrix<T,_m,_n,_Prd>& result, const size_t& ulrow, const size_t& ulcol) const
{
    assert(_m+ulcol <= m && _n+ulrow <= n) ;

    for (size_t j = 0 ; j < _m ; ++j)
        for (size_t i = 0 ; i < _n ; ++i)
            result[j*_n+i] = data[(ulrow + j) * n + ulcol+i] ;

}

これは、参照として変更するサブ マトリックスを渡すためです。

したがって、私の問題は、この関数が別のテンプレート型 (同じオブジェクト) を返す場合、コンパイラがこの関数をまったく検出しないことです。

しかし、私は以前に多くの変換演算子でこの手法を使用しましたが、それらは機能します。たとえば、これは機能します:

template<typename T, int cn, typename _Prd>
template<typename U, typename _Prd2>
Vec<T,cn,_Prd>::operator Vec<U,cn,_Prd2>() const 
{
  U temp[cn] ;
  for (int i = 0 ; i < cn ; ++i)
    temp[i] = static_cast<U>(this->data[i]) ;
  Vec<U,cn,_Prd2> v(temp) ;
  return v ;
};

アップデート2:

iamilind に従ってコードを変更しました。

template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> getMat<_m,_n>(const size_t& ulrow, const size_t& ulcol) const ;
// the declaration in the class.

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> Matrix<T,m,n,_Prd>::getMat<_m,_n>(const size_t& ulrow, const size_t& ulcol ) const 
{
    assert(_m+ulcol <= m && _n+ulrow <= n) ;
    T temp[_m*_n] ;
    for (size_t j = 0 ; j < _m ; ++j)
        for (size_t i = 0 ; i < _n ; ++i)
            temp[j*_n+i] = data[(ulrow + j) * n + ulcol+i] ;
    return Matrix<T,_m,_n,_Prd>(temp) ;
}

そして、私はそれを次のように呼びます:

Matrix<double,2,2> testmat7 = testmat2.getMat<2,2>(0,0) ;

しかし、それはコンパイルされません:

In file included from main.cpp:13:
Matrix.hpp:125: error: expected initializer before ‘&lt;’ token
In file included from main.cpp:13:
Matrix.hpp:268: error: expected initializer before ‘&lt;’ token
main.cpp: In function ‘int main(int, char**)’:
main.cpp:135: error: ‘class Matrix<double, 4ul, 4ul, std::equal_to<double> >’ has no member named ‘getMat’
main.cpp:135: error: expected unqualified-id before numeric constant

ありがとう。

4

1 に答える 1

0

この宣言があると

template <typename T, size_t m, size_t n, typename _Prd>
template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> Matrix<T,m,n,_Prd>::getMat(const size_t& ulrow, const size_t& ulcol ) const

コンパイラは、6 つのテンプレート引数を推測する必要があります。これらのうちの 4 つ (つまりT、、、、および) はm、関数を呼び出すオブジェクトから推測できます。他の 2 つ、つまりと) は推定できません。ただし、明示的に指定できます。n_Prd_m_n

Matrix<double, 4,4> testmat2(100.0);
Matrix<double,2,2> testmat4 = testmat2.getMat<2, 2>(0,0);

testmat2従属名になる場合は、追加のキーワードを挿入する必要がありますtemplate

template <int Size>
void f() {
    Matrix<double, 4, Size> testmat2(100.0);
    Matrix<double, 2, 2>    testmat4 = testmat2.template getMat<2, 2>(0,0);
}

コンパイラは、テンプレート引数を推測するために結果が代入される型を使用しません (型が使用されることもありますが、それは、準備が整ったオーバーロード セットがあり、関数ポインターまたはメンバー関数ポインターのアドレスを選択する必要がある場合に限られます)。これらのうち、私は思う)。

変換演算子は、実際には戻り値の型を持っていないため、追加の引数を推測できますが、テンプレート引数を潜在的に推測できる別の引数を取得します。その後の更新で発生するエラーは、おそらく関数の宣言方法が原因です。

template<size_t _m, size_t _n> 
Matrix<T,_m,_n,_Prd> getMat<_m,_n>(const size_t& ulrow, const size_t& ulcol) const ;

<_m, _n>後はそこgetMat()に行かないでください。

于 2012-11-22T07:12:05.217 に答える