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
std::mutex mtx;
auto lk = std::lock_guard{mtx}; // deduct to std::lock_guardstd::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()

浙公网安备 33010602011771号