繁体   English   中英

警告C4244:'argument':从'double'转换为'const int',可能会丢失数据

[英]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> 如果是这样,则Tint 所以在上面的表达式中, 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 ,因此它可以是你作为参数传递给它的任何东西。 通过参数时,不会丢失数据。

现在你知道intdouble的乘积结果是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;
}

等待! 这是正确的吗? 如果TdoubleUint怎么办? 以上问题与前一个完全相同!

所以这是第三次尝试:

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>());

这取决于TU的产品类型。 现在这是正确的, 至少要好得多。

希望有所帮助。

您的模板代码要求参数和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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM