C++17新库

在C++17中出现了一些新的库,分别是:

  • string_view
  • variant
  • filesystem
  • charconv
  • 工具库中新增加了any
  • 数学特殊函数cmath(这个是老库,但是加了新功能)

本文只列出一些常用方法或概述,具体用法见cppreference。

string_view库

位于string_view文件中,用于给字符串提供一个视图。也就是说你可以通过这个类来观察一个字符串,但是却不能更改字符串。

使用string_view的好处是在不复制字符串的情况下对字符串进行更好的观测。

在C++17之前我们一直使用const string或者const char*,const char[]来实现此类功能。但是现在我们有更加安全的string_view

string_view通过构造函数传入字符串来创建视图:

1
2
3
4
5
6
7
8
char buffer[12] = "hello world";
string str = "this is string";
string_view view1(buffer),
            view2(str),
            view3(buffer, 10);  //取前10个字符

cout<<view1<<endl;
cout<<view2<<endl;

string_view还提供迭代器来观测字符,迭代器的使用方法和其他的STL容器一样(采用begin(),cbegin(),rbegin(),crbegin()获得迭代器开头),甚至可以使用逻辑运算符来比较字符串。

需要注意的是:由于是字符串视图,所以在构造string_view的时候并不会将字符串拷贝到string_view的内存中。string_view只是提供一个观测字符串的方法。所以要时刻注意string_view对象观测的字符串失效的问题。最典型的错误如下:

1
2
3
string_view ToStringView(const string str){
    return string_view(str);
}

你也可以使用operator=来重新设置视图。对视图所做的所有事情均不会影响原字符串。

variant

定义于variant头文件中。用于取代union联合体。

variant的用途和union简直一模一样:可以存储多个值,但是每一读时刻只有一个值是有用的:

1
2
3
4
5
6
7
8
9
variant<int, float, bool> v;    //v里面可以有int,float,bool三种类型的值
v = 2;      //赋予int值
v = false;  //赋予bool值
v = 3.123f; //赋予浮点数,最后必须加f因为字面量不加f的话C++默认转换为double

cout<<std::get<float>(v)<<endl; //获得float类型,输出3.123
//cout<<std::get<int>(v)<<endl; 会抛出std::bad_variant_access异常,因为此刻只有float值是有效的
cout<<std::get<1>(v)<<endl; //通过序号获得float值(int-0, float-1, bool-2)
//cout<<std::get<0>(v)<<endl; 同理获得int是不行的

variant不允许有引用,数组或者void类型的成员。空的variant也不行(你可以用variant<monostate>代替空)

filesystem

filesystem用于文件系统。有了这个再也不用用系统API了。

这个库比较奇怪,官方说头文件是filesystem,但是我在experimental/filesystem下找到了。然而却不能用(就算链接了stdc++fs都不行)。所以这个库我其实也没用过,但是我看官方文档还是很简单的,大家上cppreference看一看吧。

云程序员

需要注意的是有些编译器使用这个库需要另外链接库,LLVM是-lc++fs, GUNC是-lstdc++fs。

charconv

这个库是在int,float,double和字符串直接转换。

我这里用不了这个库的函数,我的库里面将其删除了,所以大家cppreference吧。

云程序员

utility中增加的any

any类用于存储一个任意类型,或者什么都不存。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
any a = 2;  //直接赋值即可

//通过type()获得其typeid      通过any_cast<>来将a转换为固定类型(any本身不能直接输出)
cout<<a.type().name()<<" "<<any_cast<int>(a)<<endl;
a = 3.1415;
cout<<a.type().name()<<" "<<any_cast<double>(a)<<endl;
//cout<<any_cast<int>(a)<<endl; 不能将double强制转换为int,抛出bad_any_cast错误

a.reset();  //清空a里面的值
if(a.has_value())   //判断a是否有值
    cout<<"any has value"<<endl;
else
    cout<<"any don't has value"<<endl;

/*输出
i 2
d 3.1415
any don't has value
*/

cmath中增加的特殊数学函数

cmath中增加了一些计算特殊数学函数的函数,比如圆锥曲线积分啊,黎曼函数什么的。咱也不是搞数学的,也看不懂。有想要了解的请自行cppreference吧。

updatedupdated2023-06-182023-06-18