[英]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 );
不要忘記模板參數! 如果模板總是必須指定類型,那么使用模板將是一種皇家痛苦。 編譯器(有時)會根據您提供的參數很好地推斷出這些模板參數是什么。
這是它可以並且確實這樣做的情況之一。 在這種情況下,它推斷InputIt
是std::vector<int>::iterator
,而T
要么是std::int64_t
(您的第一個示例)或int
(您的第二個示例)。
除非您另行告訴編譯器,否則它將始終推斷0
為int
類型。 有一種方法可以告訴編譯器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.