#include
#include
#include
int main()
{
std::string s = "Hello World.";
std::string_view sw(s.c_str() , 5);
std::cout << sw;
}
Once we create a string_view, we can use its member functions. To create a substring out of a string_view, we use the .substr() member function. To create a substring, we supply the starting position index and length. To create a substring of the first five characters, we use:
#include
#include
#include
int main()
{
std::string s = "Hello World";
std::string_view sw(s);
std::cout << sw.substr(0, 5);
}
A string_view allows us to parse (not change) the data that is already in the memory, without having to make copies of the data. This data is owned by another string or character array object.
17.6 std::any
The std::any container can hold a single value of any type. This container is declared inside the header file. Example:
可以理解为一种特殊的void*(void*在解引用前也需要类型显式转换为具体特定的类型)。
#include
int main()
{
std::any a = 345.678;
std::any b = true;
std::any c = 123;
}
To access the value of an std::any object in a safe manner, we cast it to a type of our choice using the std::any_cast function:
#include
#include
int main()
{
std::any a = 123;
std::cout << "Any accessed as an integer: " << std::any_cast(a) << '
';
a = 456.789;
std::cout << "Any accessed as a double: " << std::any_cast(a) << '
';
a = true;
std::cout << "Any accessed as a boolean: " << std::any_cast(a) << '
';
}
Important, the std::any_cast will throw an exception if we try to convert, for example, 123 to type double. This function performs only the type-safe conversions.Another std::any member function is .has_value() which checks if the std::any object holds a value:
#include
#include
int main()
{
std::any a = 123;
if (a.has_value())
{
std::cout << "Object a contains a value." << '
';
}
std::any b{};
if (b.has_value())
{
std::cout << "Object b contains a value." << '
';
}
else
{
std::cout << "Object b does not contain a value." << '
';
}
}
17.7 std::variant
There is another type of data in C++ called union. A union is a type whose data members of different types occupy the same memory. Only one data member can be accessed at a time. The size of a union in memory is the size of its largest data member. The data members overlap in a sense. To define a union type in C++, we write:
union MyUnion
{
char c; // one byte
int x; // four bytes
double d; // eight bytes
};
Here we declared a union type that can hold characters or integers or doubles. The size of this union is the size of its largest data member double, which is probably eight bytes, depending on the implementation. Although the union declares multiple data members, it can only hold a value of one member at any given time. This is because all the data members share the same memory location. And we can only access the member that was the last written-to. Example:
#include
union MyUnion
{
char c; // one byte
int x; // four bytes
double d; // eight bytes
};
int main()
{
MyUnion o;
o.c = 'A';
std::cout << o.c << '
';
// accessing o.x or o.d is undefined behavior at this point
o.x = 123;
std::cout << o.c;
// accessing o.c or o.d is undefined behavior at this point
o.d = 456.789;
std::cout