[英]warning using std::accumulate(v.begin(), v.end(), 0);
為什么我會收到警告C4244 '=': conversion from '__int64' to '_Ty', possible loss of data
? 此外, auto
而不是LONGLONG
會產生此警告。
std::vector<LONGLONG>& v = m_vecEstimatedTime;
LONGLONG nEstimatedTimeTotal = std::accumulate(v.begin(), v.end(), 0); // warning C4244 '=': conversion from '__int64' to '_Ty'
std::accumulate
的返回類型和匯總值的類型由傳遞的初始值決定。 對於0
它將是int
。
如果類型應該是LONGLONG
,則可以將初始值指定為:
LONGLONG nEstimatedTimeTotal = std::accumulate(v.begin(), v.end(), static_cast<LONGLONG>(0));
std::accumulate
將范圍內的值相加。 本質上,它看起來像這樣:
template <class Iter, class Accum>
Accum accumulate(Iter first, Iter last, Accum x) {
while (first != last)
x += *first++;
return x;
}
編譯器警告您的問題是,在accumulate(v.begin(), v.end(), 0)
,內部總和將LONGLONG
值添加到int
值; 這就是可能發生精度損失的地方。 auto
不會刪除該警告,因為罪魁禍首不僅僅是nEstimblahblah
; 內部類型也會失去精度。
為了修復它,在這種情況下,第三個參數應該與添加的東西具有相同的類型。 這樣做的明顯方法是使用顯式類型:
LONGLONG total = std::accumulate(v.begin(), v.end(), static_cast<LONGLONG>(0));
這種方法的缺點是一切都是硬編碼的。 如果你想改變向量元素的類型,你必須在三個地方改變它。 您可以對元素類型使用 typedef:
typedef LONGLONG elem_t;
std::vector<elem_t>& v = whatever;
elem_t total = std::accumulate(v.begin(), v.end(), static_cast<elem_t>(0));
或者,對於更靈活的代碼,請鍵入整個內容:
typedef std::vector<LONGLONG> ctr_t;
typedef typename ctr_t::value_type elem_t;
ctr_t& v = whatever;
elem_t total = std::accumulate(v.begin(), v.end(), static_cast<elem_t>(0));
使用該版本,您可以在不更改其余代碼的情況下更改元素類型,並且可以在不更改其余代碼的情況下更改容器類型。 另一方面,這個版本更加冗長,而且可能過於靈活。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.