这个问题源自我昨天收到的answer。对于以下函数,如果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;
}
通过这个添加,以上两种情况都可以正确编译和运行。
答案 0 :(得分:3)
我认为必须涉及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>)
不一定是特殊情况。
答案 1 :(得分:2)
我认为如果T和U不同,则会调用另一个函数,因为编译器是正确的,V不能推断,周期。即使我不能推断你认为该参数应该是什么。 Here's proof that the second doesn't compile and run either,这意味着在这种情况下调用了不同的函数。显而易见的解决方案是简单地删除class V
模板参数类型,并简单地使用推导的类型。也许你想要一些more like this?
再次查看您的代码,您说的代码失败的是complex * matrix
,而第二个代码是matrix*matrix
。还有哪些operator*
被定义了?
<小时/> 不相关的接受参数的三种常用方法是
T
,const T&
或T&&
。没有理由拥有const T
参数类型。我相信你错过了&
?
答案 2 :(得分:2)
问题不在于T
和U
是相同的,但在提及V
类型的函数原型中有注意到。
考虑到你使用V
来声明你返回的B,并且你将返回类型定义为T()* U(),我想知道matrix<V>
应该是什么。
我希望B和返回类型为matrix<decltype(declval<T>()*declval<U>())>
,没有V(不应该在参数列表中)