簡體   English   中英

使用 std::accumulate(v.begin(), v.end(), 0) 發出警告;

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM