c17特性初览

structed bindings

结构化绑定,将指定的名称绑定到初始化对象的子对象or元素,能绑定数组对象、类似元组的类型、成员变量。

inline variable

内联变量,能直接在头文件中对static变量进行初始化。

class Test {
public:
inline static int a = 10;
};

fold expression

折叠表达式: 一元右折叠、一元左折叠、二元右折叠、二元左折叠

charconv

新增两个字符串转换函数: std::to_chars(), std::from_chars()

std::variant

std::variant,是一个可以存储多种不同类型值但一次只能存储一种类型值的模板类,它类似于一个union类型,但是更加安全和易于使用。在错误的情况下variant不持有任何值。

#include <iostream>
#include <variant>

int main() {
std::variant<int, std::string> x = "abc";
// index 获取当前variant持有变量的类型,返回该类型的索引
std::cout << "index: " << x.index() << std::endl;
// std::get 获取variant中该类型的值
std::cout << std::get<std::string>(x) << std::endl;
x = 123;
std::cout << "index: " << x.index() << std::endl;
std::cout << std::get<int>(x) << std::endl;
return 0;
}

std::optional

std::optional用来管理一个可能存在也可能不存在的值。当optional对象转换成bool类型,如果存在值返回true,否则返回false。

#include <iostream>
#include <optional>

int main() {
std::optional<std::string> b = std::make_optional("hello");
if(b){
std::cout << *b << std::endl;
}

std::optional<std::string> c;
if(!c){
std::cout << "no value" << std::endl;
}
return 0;
}

std::any

std::any 是一种可以存储任意可拷贝构造类型值的类型安全容器。

#include <iostream>
#include <any>

int main() {
std::any a = 1;
std::cout << a.type().name() << " " << std::any_cast<int>(a) << std::endl;
a = 3.14;
std::cout << a.type().name() << " " << std::any_cast<double>(a) << std::endl;
return 0;
}

std::apply

#include <iostream>
#include <tuple>

int add(int first, int second) { return first+second; }
int add_lambda(int first, int second) { return first+second; }

int main() {
std::cout << std::apply(add, std::pair(1, 2)) << std::endl;
std::cout << std::apply(add_lambda, std::tuple(2, 3)) << std::endl;
return 0;
}

std::filesystem

std::filesystem是一个lib,提供一些列操作文件的方法。
文件路径使用std::path类来表示,操作文件的方法都是基于std::path实现的。

#include <iostream>
#include <filesystem>

namespace fs = std::filesystem;

int main() {
fs::path p1("/home/jzy/test/test");
if(p1.has_parent_path()){
std::cout << "parent path: " << p1.parent_path() << std::endl;
}
for(auto& tmp : p1){
std::cout << "iter: " << tmp << " ";
}
std::cout << std::endl;
if(!fs::exists(p1)){
fs::create_directory(p1);
}
fs::path old_path("/home/jzy/test/test.txt");
fs::path new_path("/home/jzy/test/test");
if(!fs::exists(new_path))
fs::copy(old_path, new_path);
fs::remove_all(new_path);
std::cout << "pwd: " << fs::current_path() << std::endl;
// 获取目录下所有文件
std::cout << "all path: " << std::endl;
for(auto& p : fs::directory_iterator{fs::current_path()}){
std::cout << p << std::endl;
if(fs::is_directory(p)){
std::cout << "directory" << std::endl;
}else if(fs::is_regular_file(p)){
std::cout << "file" << std::endl;
}
}
return 0;
}

std::shared_mutex

shared_mutex类是共享锁,用来保护共享数据不被多个线程访问。与mutex相比,共享锁有两个访问级别:

  • 共享 - 多个线程可以共享同一互斥对象的所有权
  • 独占 - 只有一个线程可以拥有互斥对象

可以用来实现读写锁。

参考