![](/img/trans.png)
[英]Warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
[英]warning C4244: 'argument' : conversion from 'double' to 'const int', possible loss of data
我正在定义'*'运算符以使用'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。 我错了吗? 如果没有,为什么不适用于这种情况?
intArray1 = intArray1*2.5;
我猜intArray1
的类型为NumericArray<int>
。 如果是这样,则T
为int
。 所以在上面的表达式中, 2.5
是一个double
将被转换为int
,因为它作为参数传递给重载的operator*(const int&)
。
这也意味着,2.5(双)变为2(整数), 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
,那么为什么在你传递double
情况下从函数返回NumericArray<int>
? 我认为如果参数是double
,返回NumericArray<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>());
这取决于T
和U
的产品类型。 现在这是正确的, 至少要好得多。
希望有所帮助。
您的模板代码要求参数和NumericArray元素具有相同的时间,这就是为什么C ++在乘法之前将arg截断为2的原因。
要修复它,你应该编写类似的代码
template <class U> template<class T>
NumericArray<T> NumericArray<T>::operator * (const U& factor) const
{
/***/
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.