我是C ++ 17的新手,我试图理解decltype
关键字以及它如何与auto
配对。
下面是一段产生意外结果的代码片段。
#include <typeinfo>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int16_t mid = 4;
auto low = mid - static_cast<int16_t>(2);
auto hi = mid + static_cast<int16_t>(2);
int16_t val;
cin >> val;
val = std::clamp(val,low,hi);
return 0;
}
令人惊讶的是,编译器告诉我clamp
不匹配,low
和high
是int
。如果我将auto
改为int16_t
,那么世界上一切都很好,所有类型都是int16_t
。
我正在提出的问题是,当所有类型都是auto
时,为什么low
将hi
和int
投射到int16_t
?这是decltype
的一个很好的用例吗?
即使在阅读cppreference.com之后,我也不完全了解decltype
是如何工作的,所以请原谅我的无知。
问题不在于auto
。当你减去两个int16_t
值时,结果是int
。我们可以用this code here来证明它:
#include <iostream>
#include <cstdint>
using namespace std;
template<class T>
void print_type(T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main() {
int16_t a = 10;
int16_t b = 20;
print_type(a);
print_type(b);
print_type(a - b);
return 0;
}
a
和b
都是short int
s,但是当你加或减时它会产生一个常规的int
。这有助于防止溢出/并且也是为了向后兼容。
这种现象称为usual arithmetic conversions。它在C和C ++标准中定义,并且(粗略地说)将任何小于int
的东西转换为int
。它也可以转换更大的类型。花点时间阅读一下,你会经常需要它。