簡體   English   中英

C ++模板中的類型優先級和整數類型

[英]Type precedence and integer types in C++ templates

我在編碼練習中使用了std :: accumulate,遇到了一些我想更全面理解的行為。

累積的簽名是:

T accumulate( InputIt first, InputIt last, T init );

如果我有類似的代碼:

std::vector<int> a = {..};
int64_t zero = 0;
int64_t csum = std::accumulate(a.begin(), a.end(), zero);

它按我的預期工作。 如果我將其更改為:

std::vector<int> a = {..};
int64_t csum = std::accumulate(a.begin(), a.end(), 0);

然后會溢出,因為(我認為)“ 0”的類型被確定為32位整數,並且此值覆蓋了我實際指定的返回類型(因為可以將普通整數存儲在64位整數中)。

據此,我推斷出編譯器正在生成如下所示的累加:

int accumulate( InputIt first, InputIt last, int init );

int64_t accumulate( InputIt first, InputIt last, int64_t); 

我是否記得有一些規則可以將此推論推廣到其他情況?

累積的簽名是:

 T accumulate( InputIt first, InputIt last, T init ); 

累積的簽名是

template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );

不要忘記模板參數! 如果模板總是必須指定類型,那么使用模板將是一種皇家痛苦。 編譯器(有時)會根據您提供的參數很好地推斷出這些模板參數是什么。

這是它可以並且確實這樣做的情況之一。 在這種情況下,它推斷InputItstd::vector<int>::iterator ,而T要么是std::int64_t (您的第一個示例)或int (您的第二個示例)。

除非您另行告訴編譯器,否則它將始終推斷0int類型。 有一種方法可以告訴編譯器0是其他類型:

std::accumulate(a.begin(), a.end(), 0L)   // T is long int
std::accumulate(a.begin(), a.end(), 0LL)  // T is long long int
std::accumulate(a.begin(), a.end(), 0U)   // T is unsigned int
std::accumulate(a.begin(), a.end(), 0UL)  // T is unsigned long int
std::accumulate(a.begin(), a.end(), 0ULL) // T is unsigned long long int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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