нет соответствующей функции при возврате шаблона другого типа

Я написал простой матричный класс шаблона, функция 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 ;
};

Update2:

Я изменил код в соответствии с iammilind:

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 ‘<’ token
In file included from main.cpp:13:
Matrix.hpp:268: error: expected initializer before ‘<’ 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

Благодарю.

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 аргументов шаблона. Четыре из них (т.е. T, m, 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() не ходи туда.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector