学习内容
本节主要学long long各版本用法的异同,后续请关注 学习C++11/14/17/20/23关键词版本更替 ,将持续更新~~
long long出现为了解决传统整形精度不足问题,long long是long long int的简写,unsigned long long 是 unsigned long long int 的简写,最小宽度为64位
取值范围:
有符号long long:补码表示 范围是 [ -2^64,2 ^64 -1 ]
无符号 long long : 范围是 [ 0 , 2 ^ 64 -1]
字面量后缀: 标准为 " ll / LL "为 long long 字面量后缀," ull / uLL / ULL / Ull "为unsigned long long 字面量后缀
头文件使用 提供固定宽度别名 : int64_t ( long long) , uint64_t (unsigned long long )
C++11 正式纳入标准内置基本类型
1、废弃编译器扩展的非标准写法( __int64兼容写法)
2、强制规定 ll / LL , ull / ULL 为标准后缀
3、适配C++11新特性
- auto推导可正确识别 long long , auto x = 1L ;
- 模版参数可接受long long 类型 , template struct A{};
- 右值引用(&&)支持long long,移动语义可作用于64位整数
- nullptr与 long long 指针可正常配合, long long * pL = nullptr;
4、新增 int64_t / uint64_t / int_least64_t / int_fast64_t等 , 与 long long 映射
5、/ 支持long long 的输出 (cout)
6、增加64位数学函数重载 (abs( long long )),解决 abs仅支持int / long型问题
C++14 细节完善
1、增强constexpr对long long 支持,允许在编译期进行复杂算法运算、逻辑运算、条件判断
cpp
constexpr long long calc() { return 100LL + 200 LL ; }
constexpr long long res = calc();
2、二进制字面量支持 long long 后缀 , 0B / 0b 均代表二进制
constexpr long long bin = 0b1010LL;
3、数字分隔符适配long long ,提升可读性,支持所有整形
cpp
long long big_num = 123'345'567'789'34LL;
4、完善泛型变成中类型推导,使得auto正确推导long long
cpp
auto lam = [](auto x) { return x * 2LL ; }
long long res = lam(100LL);
5、 / 新增long long 重载函数
C++17 核心增强
1、新增标准64位整数的上下先常量:
LLONG_MAX/LLONG_MIN: long long 最大值,最小值
ULLONG_MAX: unsigned long long 最大值
INT64_MAX / INT64_MIN / UINT64_MAX : int64_t / uint64_t最大值/最小值
2、新增类型特性模版,精准判断 long long ,在<type_traits>新增编译期类型判断,替代typeid
std::is_long_long_v , 判断T是否为long long
std::is_unsigned_long_long_v , 判断T是否为unsigned long long
3、结构化绑定
cpp
std::pair<long long ,std::string > p = {112LL , "test" };
auto [ num , flag ] = p;
4、constexpr if适配long long 编译期分支
cpp
template <typename T>
T get_max() {
if constexpr (std::is_long_long_v<T>) {
return LLONG_MAX; // 编译期分支,仅当T是long long时编译
} else if constexpr (std::is_unsigned_long_long_v<T>) {
return ULLONG_MAX;
} else {
return 0;
}
}
long long ll_max = get_max<long long>(); // 编译期返回LLONG_MAX
5、部分标准库容器的resize/reverse支持long long作为参数(之前仅支持size_t)
6、long long与其他整形的隐式转换规则 (int 转为long long是安全转换,反之是窄化转换)
C++20特性增强
编译期数组初始化( constexpr std::array <long long , 3 > arr = { 1LL , 2LL , 3LL };)
编译期标准库函数调用( constexpr long long sum = std::accumulate( arr.begin() , arr.end() , 0LL ;)
编译期数值转换(constexpr int x = static_cast(100LL);)
Concepts精准约束long long类型,替代传统std::is_integral
std::signed_integral:约束有符号整数
std::unsigned_integral: 约束无符号整数
cpp
template< class T>
requires std::is_long_long_v<T> T doubleNum(T x) { return x* 2LL; }
template <std::signed_integral T>
T add(T x) { return x + x ; }
doubleNum(100LL);
doubleNum(1); //报错 ,必须是long long类型
add(200LL);
3、Ranges适配long long,包括范围迭代、范围算法、视图转换
cpp
vector<long long > v = { 1LL , 2LL , 3LL };
long long sum = v | views::filter( [](auto x){ return x > 1LL; } ) | views::fold_left( 0LL , plus<>() );
4、协程中的long long 支持,可作为协程的参数/返回值
5、窄化转换检查增强
cpp
int a = 10000000000LL; //error ,窄化转换不允许
int b = static_cast<int> (10000000000LL); //OK , 显式转换
C++23 核心增强
1、新增整型字面量的通用后缀z/Z(对应ssize_t) 和 uZ / UZ (对应size_t),并支持与long long后缀配合
cpp
vector<long long> vec(100);
for(ssize_t i = 0 ;i <vec.size(); ++i) { vec[i] = i * 1LLz ; }
2、在中新增64位整型高精度运算,支持long long的溢出安全运算
cpp
long long a = LLONG_MAX;
long long b = 1LL;
long long res ;
if ( add_overflow( a, b ,res)) { cout << " add overflow " << endl; } //溢出检测,结果存入res
long long satSum = add_sat( a, b ); //溢出时取最大值/最小值
3、标准化Modules中long long的导入规则,无需在模块导入 / 即可使用,LLONG_MAX等常量需要import std; 显式导入对应标准模块
4、完善 std::optional / std::expected <long long , Error> 支持,允许从字面量初始化
cpp
optional<long long> opt = 123LL;
5、禁止long long非法窄化转换,必须强制显式转换static_cast
6、在<type_traits>中新增编译期数值范围判断模版,检测long long是否溢出
cpp
template< long long N>
struct CheckOverflow { static constexpr bool value = ( N > LLONG_MAX) || (N < LLONG_MIN); };
static_assert ( !CheckOverflow<100LL>::value , "未溢出");
static_assert(CheckOverflow<10000000000000000000LL>::value, "溢出");