我正在定义'*'运算符以使用'NumericArray'类模板。代码如下:
template <class T>
NumericArray<T> NumericArray<T>::operator * (const T& factor) const
{
NumericArray<T> newArray(Size());
for (int i = 0; i < Size(); i++)
newArray[i] = factor * GetE(i);
return newArray;
}
当'factor'参数是double时,我尝试使用'int'(NumericArray)类型的'NumericArray'和'*'运算符:
intArray1 = intArray1*2.5;
我收到以下编译器警告:
warning C4244: 'argument' : conversion from 'double' to 'const int', possible loss of data
并且'factor'arg在与'NumericArray'对象的元素相乘之前从2.5截断到2(一个int)。有没有办法防止这种情况发生?我认为在C ++中它是默认协议的简单问题,其中int * double = double。我错了吗?如果没有,为什么不适用于这种情况?
答案 0 :(得分:9)
intArray1 = intArray1*2.5;
我猜intArray1
的类型为NumericArray<int>
。如果是这样,则T
为int
。因此,在上面的表达式中,作为2.5
的{{1}}将转换为double
,因为它将作为参数传递给重载的int
。
这也意味着,2.5(双)变为2(整数),operator*(const 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
}
的两次使用不要感到惊讶。评论说出了他们的意图。如果你理解得那么好,那么你也明白参数 now 是template
而不是U
,它可以独立于T
因此它可以是无论你把它作为论点传递给它。在通过论证时,不会丢失数据。
现在您知道T
和int
的产品原来是double
,那么为什么在您通过{{1}时从函数返回double
它呢?如果参数为NumericArray<int>
,我认为返回double
会更有意义。所以以下似乎是正确的实现:
NumericArray<double>
<强>等待!这是正确的吗?如果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
为double
,该怎么办?以上问题与前一个问题完全相同!
所以这是第三次尝试:
U
所以返回类型是:
int
其中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>());
的产品类型。现在这是正确的,至少好多了。
希望有所帮助。
答案 1 :(得分:-1)
你的模板代码要求参数和NumericArray元素具有相同的时间,这就是为什么C ++在乘法之前将arg截断为2的原因。
要解决此问题,您应该编写类似
的代码template <class U> template<class T>
NumericArray<T> NumericArray<T>::operator * (const U& factor) const
{
/***/
}