string_view
string_view是字符串的视图。C++提供的string效率是有点慢的,因为内存的开辟都在堆上。而C++17的string_view可以提高一些效率。所谓的SV(string_view)就是一个const字符串加上一个长度,你可以读取该字符串,但是你不能修改。
class string_view{
private:
const char* data_;
size_t size_;
};
这玩意也不是什么新东西了,C++17之前,就有人这样搞,因为SV对象只有一个指针和一个size_t的对象,所以拷贝和创建是非常轻量级的,传参可以直接by-value,使用起来体验非常好。
因为是string的视图,所以接口也都跟string很相似。
//构造函数
std::string str{"hello"};
const char* c_str = "hello";
char strings[]{"hello"};
std::string_view sv0; //默认构造
std::string_view sv1{"hello"}; //字符字面量
std::string_view sv2{str}; //string
std::string_view sv3{c_str}; //pointer
std::string_view sv4{strings}; //pointer
std::string_view sv5{nullptr}; //error !!
std::string_view{ std::begin(str), std::end(str) }; //iterator
std::string_view sv5{sv1};
string_view的构造函数类似string,跟字符串有关的都可以使用,而且也支持iterator构造。string_view不要用nullptr来初始化。
string_view也支持拷贝构造,这样它们底层的指针都指向同一个字符串。
std::string str1{std::rbegin(str), std::rend(str)}; // ok
std::string_view sv6{std::rbegin(str), std::rend(str)}; //error
用来举证底层是一个指针而已。不支持反向的"观察".
C++引入了std::literals::string_view_literals命名空间,重载了operator""sv操作符,
using namespace std::literals::string_view_literals;
void recv_string_view(std::string_view sv);
recv_string_view("hello"sv); //不需要"hello"->string_view的隐式转换了
//”hello“sv本身就是string_view字面常量
Visitor
SV也提供了operator[],
std::string_view sv{"hello"};
char first = sv[0];
sv[0] = 'a'; // error !不能修改
span
你想,string只不过是特殊的char数组罢了,string有了视图,那是不是所有的顺序表都可以有视图?没错,span就是这个东西。
我认为span与string_view最大的不同是,span支持修改。
template <class T>
class span{
private:
T* data_; //非const
size_t size_;
};
我们可以通过span去管理内存连续的顺序表,比如普通的数组,std::vector,std::array等等。
在vector, array上,提供的自然是效率,因为span也是拷贝,构造简单的,代价很小。span在数组上也起了很大作用。在这方面,跟string_view一样。
而且,我们可以通过span管理数组,而非简简单单的“观察”。因为数组这个东西吧,不太面向对象。我们无法通过一个数组的对象得到数组的一系列特性。
int array[]{1, 2, 3};
array.size(); //no,C++没有这样的东西
这里,我们无法仅仅通过array这个对象得到它的长度。而且array传参还会退化。有了span,我们可以实现。
int array[]{1, 2, 3};
std::span sp{array};
sp.size(); // 3
sp[0] = 3; //ok,支持修改
span可以理解为一个面向对象版本的数组。而且当span发生错误时,我们会给出明确的断言,out of span range,使用起来也很方便,且不用担心效率。
span的接口也非常简单,不再赘述。