intArray1 = intArray1*2.5;
我猜intArray1
是类型NumericArray<int>
。如果是这样,那么T
就是int
。所以在上面的表达式中,2.5
adouble
将被转换为int
,因为它operator*(const int&)
作为参数传递给重载。
这也意味着 2.5 (double) 变成 2 (int) 并且factor
基本上是2
. 数据丢失!
解决此问题的一种方法是将函数模板(作为类模板的成员)用作:
template<class T> //this is for class templatwe
template<class U> //this is for function template
NumericArray<T> NumericArray<T>::operator * (const U& factor) const
{ //^^^^^^^ it is U now!
//your code
}
不要template
对上述定义中的两个用法感到惊讶。评论说明了它们的用途。如果你理解得很好,那么你也明白参数现在是U
而不是T
,它可以独立于T
,因此它可以是你作为参数传递给它的任何东西。只要传递参数,就不会丢失数据。
int
现在你知道和的乘积double
是double
,那么为什么NumericArray<int>
要从函数返回以防万一你传递double
给它呢?NumericArray<double>
我认为如果参数是return 更有意义double
。所以以下似乎是正确的实现:
template<class T> //this is for class templatwe
template<class U> //this is for function template
NumericArray<U> NumericArray<T>::operator * (const U& factor) const
{ //^^^ CHANGED
NumericArray<U> newArray(Size()); //CHANGED HERE TOO!
for (int i = 0; i < Size(); i++)
newArray[i] = factor * GetE(i);
return newArray;
}
等待!现在这正确吗?如果T
isdouble
和U
isint
怎么办?上面的问题和上一个完全一样!
所以这是第三次尝试:
template<class T> //this is for class templatwe
template<class U> //this is for function template
NumericArray<decltype(std::declval<T>() * std::declval<U>())>
NumericArray<T>::operator * (const U& factor) const
{
typedef decltype(std::declval<T>() * std::declval<U>()) R; //define R
NumericArray<R> newArray(Size()); //CHANGED HERE!
for (int i = 0; i < Size(); i++)
newArray[i] = factor * GetE(i);
return newArray;
}
所以返回类型是:
NumericArray<R>
哪里R
是:
decltype(std::declval<T>() * std::declval<U>());
这取决于 和 的产品T
类型U
。现在是正确的,至少好多了。
希望有帮助。