C++17新特性
C++17新特性
语言特性
使用auto声明非类型模板参量
折叠表达式
提供模板参数包的折叠
template <typename... Args>
bool logicalAnd(Args... args) {
// 二元折叠
return (true && ... && args);
}
bool b = false;
bool& b2 = b;
logicalAnd(b, b2, true); // == false
template <typename... Args>
auto sum(Args... args) {
// 一元折叠
return (... + args);
}
sum(5, 5.0, 7); // == 17
内联变量
constexpr lambda
使用constexpr
完成编译时的lambda
表达式
列表初始化推导新规则
auto x = {1, 2, 3}; // deduct to std::initializer_list<int> before ,now deduct to int
嵌套命名空间
这个特性使命名空间嵌套更加简洁:
// before c++17
namespace A{
namespace B{
namespace C{
int i;
}
}
}
// c++17
namespace A::B::C{
int i;
}
结构绑定
这个特性可以用于解结构初始化,使用方式为auto [x,y,z] = expr;
当expr
为类元组对象时,其中的元素将对应绑定到x
,y
,z
。类元组对象包括std::pair
, std::turple
, std::array
等。
// first example
using Pair = std::pair<int, int>;
Pair init(){
return Pair{0, 0};
}
const auto [x, y] = init();
x; // x == 0
y; // y == 0
// second example
using u_map = std::unordered_map<std::string, int>;
u_name mapping{
{"a", 1},
{"b", 2},
{"c", 3}
};
// destructure by reference
for (const auto [key, value] : mapping){
cout << key << ":" << value << endl;
}
选择语句初始化器
-
if initializer
// before c++17 std::mutex mtx; { std::lock_guard<std::mutex> lk(mtx); if (v.empty()) v.push(val); } // c++17 std::mutex mtx; { if (std::lock_guard<std::mutex> lk(mtx); v.empty()){ v.push(val); } }
-
switch initializer
// before c++17 A apple(args); switch(auto s = apple.stat()){ // body } // c++17 switch(A apple(args); auto s = apple.stat()){ // body }
constexpr if
用于编写依赖于编译时条件实例化的代码
UTF-8 字面字符
```c++
char c = u8'a';
```
枚举列表直接初始化
枚举现在能够使用列表进行初始化
```c++
enum byte: unsigned char{};
byte a = {0};
byte d = byte{256};
```
[[nodiscard]] [[fallthrough]] [[maybe_unused]] 属性
__has_include宏操作符
这个特性可以用来检查库是否可以被引入。
```c++
#ifdef __has_include
#if __has_include(<iostream>) // 如果能够引入,返回true
#include <iostream>
#define have_iostream 1
#else
#define have_iostream 0
#endif
```
类模板参数推导(CTAD)
这个特性,使类模板的参数也能够进行推导
```c++
std::vector nums{1, 2, 3}; // deduct to std::vector<int>
std::mutex mtx;
auto lk = std::lock_guard{mtx}; // deduct to std::lock_guard<std::mutex>
auto p = std::pair{0.2, 0.3}; // deduct to std::pair<int, int>
```
库特性
std::variants
相当于类型安全的union
,同时只能存在一个值
std::variant<int, int, double> v{1.20};
std::get<double>(v); // 1.20
std::get<2>(v); // 1.20
std::optional
std::optional<std::string> create(bool b) {
if (b) {
return "cts";
} else {
return {};
}
}
create(false).value_or("mx"); // == "mx"
create(true).value(); // == "cts"
std::any
类型安全的容器,存放任意类型的单值。
std::any x{1};
any_cast<int>(x);
std::any_cast<int&>(x) = 10; // x==10
int s = any_cast<int>(x); // 这一步会将x存储的值转换为一个左值。
std::string_view
非所有权字符串引用
std::invoke
唤醒一个有参数的可调用对象
std::apply
唤醒一个有参数元组的可调用对象
std::filesystem
提供操作文件系统目录、文件和路径的标准方式。
std::byte
提供一个以字节表示数据的标准方式,与char
和unsigned char
相比的优点是byte
对象非字符类型和算术类型,只能够使用位操作。
std::byte x {0};
std::byte y {0xAA};
std::byte z = x & y;
int i = std::to_integer<int>(z); // 0
map和set的分片
并行算法
增加了`find`, `copy`, `sort`的并行执行操作`par`并行, `seq`顺序, `par_unseq`并行非顺序
```c++
std::vector v;
std::find(std::execution::par, v.begin(), v.end(), 2);
```
std::sample
`sample`给定学列中的若干个元素,每个元素都有一个均等的被挑选的机会。
std::clamp
`clamp`的作用是获取一个在由高值、低值范围限定的给定值。
std::reduce
与`std::accmulate`类似,在`<numeric>`中。
prefix sum algorithms
`inclusive_scan`和`exclusive_scan`
GCD (great common divisor) 和 LCM (least common multiple)
最大公约数和最小公倍数,最小公倍数是基于最大公约数进行计算的
```c++
const int a = 9;
const int b = 3;
std::gcd(a, b); // 3
std::lcm(a, b); //
```
std::not_fn
返回给定函数结果的否定值
字符串转换to/from数字
- `to_chars()`
- `from_chars()`
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)