Этот вопрос проистекает из ответ Я получил вчера. Для следующей функции я получаю ошибку couldn't deduce template parameter ‘V’
если оба T
а также U
являются std::complex<double>
, Если T
а также U
отличаются, функция компилируется и работает как задумано.
template<class T, class U, class V>
auto operator*(const T a, const matrix<U> A) -> decltype(std::declval<T>()*std::declval<U>())
{
matrix<V> B(A.size(1),A.size(2));
for(int ii = 0; ii < B.size(1); ii++)
{
for(int jj = 0; jj < B.size(2); jj++)
{
B(ii,jj) = a*A(ii,jj);
}
}
return B;
}
Использование заключается в следующем:
std::complex<double> a1;
matrix<std::complex<double> > A1;
double a2;
matrix<std::complex<double> > A2;
/* ... */
matrix<std::complex<double> > B1 = a1*A1; // Compiler error
matrix<std::complex<double> > B2 = a2*A2; // Compiles and runs fine.
Я должен также упомянуть, что я компилирую с включенным g ++ 4.7.3 и C ++ 11.
РЕДАКТИРОВАТЬ:
Обход, который я нашел, состоит в том, чтобы также предоставить этот шаблон функции:
template<class T>
matrix<T> operator*(const T a, const matrix<T> A)
{
matrix<T> B(A.size(1),A.size(2));
for(int ii = 0; ii < B.size(1); ii++)
{
for(int jj = 0; jj < B.size(2); jj++)
{
B(ii,jj) = a*A(ii,jj);
}
}
return B;
}
С этим дополнением оба приведенных выше случая компилируются и работают правильно.
Я думаю, что должна быть еще одна перегрузка operator*
участвует, потому что V
не могу выводится с учетом декларации:
template<class T, class U, class V>
auto operator*(const T a, const matrix<U> A)
-> decltype(std::declval<T>()*std::declval<U>());
Единственный способ вызвать эту функцию — указать V
явно, например, operator*<int, long, long>(...)
,
Изменить: глядя на подпись для operator*(T, matrix<T>)
во втором примере кода может показаться, что ваш первый пример кода должен выглядеть так:
template<class T, class U>
auto operator*(const T a, const matrix<U>& A) -> matrix<decltype(a*A(0,0))>
{
matrix<decltype(a*A(0,0))> B(A.size(1),A.size(2));
for(int ii = 0; ii < B.size(1); ii++)
{
for(int jj = 0; jj < B.size(2); jj++)
{
B(ii,jj) = a*A(ii,jj);
}
}
return B;
}
operator*(T,matrix<T>)
не должно быть необходимым в качестве особого случая.
Проблема не в том T
а также U
такие же, но в прототипе функции есть упоминание о V
тип.
Учитывая, что вы используете V
чтобы объявить B, что вы возвращаете, и что вы определяете тип возвращаемого значения как T () * U (), мне интересно, что matrix<V>
должно быть.
Я ожидаю, что B и тип возвращаемого значения будет matrix<decltype(declval<T>()*declval<U>())>
без V (этого не должно быть в списке параметров)
Я думаю, что если T и U различны, то вызывается другая функция, потому что компилятор прав, V не может быть выведено, точка. Даже я не могу понять, что вы думаете, что параметр должен быть. Вот доказательство того, что второй не компилируется и не запускается либо, Это означает, что в этом случае вызывается другая функция. Очевидное решение состоит в том, чтобы просто удалить class V
тип параметра шаблона, и просто используйте выведенный тип. Может быть, вы хотели что-то больше похоже на это?
Глядя на ваш код еще раз, тот, который вы говорите, терпит неудачу complex * matrix
в то время как второй matrix*matrix
, что другое operator*
определены?
Несвязанные, три нормальных способа принять параметры T
, const T&
, или же T&&
, Там очень мало причин иметь const T
тип параметра. Я полагаю, что вам не хватает &
?