文章目录
-
- std::optional
- std::string_view的使用
- std::variant使用
- [std::function 与 std::bind函数](#std::function 与 std::bind函数)
- std::forward使用
std::optional
std::optional
是 C++17 中引入的一个模板类,它可以表示一个可能不存在的值。std::optional
的使用方法非常简单,它可以用于任何类型,包括内置类型、自定义类型和 STL 容器等。
以下是 std::optional
的一些常用操作:
std::optional<T>
:表示一个可能不存在的类型为T
的值。std::nullopt
:表示一个不存在的值。std::optional<T>::value
:获取std::optional<T>
中的值,如果不存在则抛出异常。std::optional<T>::value_or
:获取std::optional<T>
中的值,如果不存在则返回指定的默认值。std::optional<T>::has_value
:判断std::optional<T>
是否存在值。std::optional<T>::reset
:将std::optional<T>
的值重置为不存在。
以下是一个使用 std::optional
的示例代码:
cpp
#include <iostream>
#include <optional>
std::optional<int> divide(int a, int b) {
if (b == 0) {
return std::nullopt;
} else {
return a / b;
}
}
int main() {
auto result = divide(10, 2);
if (result.has_value()) {
std::cout << "The result is " << result.value() << std::endl;
} else {
std::cout << "Cannot divide by zero" << std::endl;
}
auto result2 = divide(10, 0);
if (result2.has_value()) {
std::cout << "The result is " << result2.value() << std::endl;
} else {
std::cout << "Cannot divide by zero" << std::endl;
}
return 0;
}
std::string_view的使用
std::string_view是C++17标准中引入的一种轻量级字符串视图类型,可以用于表示字符串的一部分或整个字符串,而不需要进行内存分配或拷贝。下面是一个std::string_view的使用示例:
cpp
#include <iostream>
#include <string_view>
int main() {
std::string str = "Hello, world!";
std::string_view view1(str); // 从std::string构造std::string_view
std::string_view view2(str.data() + 7, 5); // 从字符指针和长度构造std::string_view
std::cout << view1 << std::endl; // 输出整个字符串
std::cout << view2 << std::endl; // 输出"world"
return 0;
}
在上面的示例中,我们首先定义了一个std::string类型的字符串str,然后使用std::string_view类型的view1和view2表示字符串的一部分或整个字符串。其中,view1使用std::string类型的构造函数进行构造,而view2使用字符指针和长度进行构造。最后,我们使用std::cout输出了view1和view2表示的字符串。
需要注意的是,std::string_view类型只是字符串的一个视图,不拥有字符串的内存,因此需要确保原始字符串的生命周期大于或等于std::string_view类型的生命周期。同时,std::string_view类型也不支持修改字符串,只能用于读取字符串的内容。
std::variant使用
std::variant
是 C++17 中引入的一个模板类,它可以表示多个可能的类型。std::variant
的使用方法非常简单,它可以用于任何类型,包括内置类型、自定义类型和 STL 容器等。
以下是 std::variant
的一些常用操作:
std::variant<Ts...>
:表示多个可能的类型Ts...
。std::get<N>(std::variant<Ts...>&)
:获取std::variant<Ts...>
中的第N
个类型的值,如果类型不匹配则抛出异常。std::get_if<N>(std::variant<Ts...>*)
:获取std::variant<Ts...>
中的第N
个类型的指针,如果类型不匹配则返回nullptr
。std::variant<Ts...>::index()
:获取std::variant<Ts...>
中当前值的类型索引。std::variant<Ts...>::valueless_by_exception()
:判断std::variant<Ts...>
是否存在值。
以下是一个使用 std::variant
的示例代码:
cpp
#include <iostream>
#include <variant>
int main() {
std::variant<int, double, std::string> v;
v = 10;
std::cout << std::get<int>(v) << std::endl;
v = 3.14;
std::cout << std::get<double>(v) << std::endl;
v = "hello";
std::cout << std::get<std::string>(v) << std::endl;
if (auto p = std::get_if<int>(&v)) {
std::cout << "The value is " << *p << std::endl;
} else if (auto p = std::get_if<double>(&v)) {
std::cout << "The value is " << *p << std::endl;
} else if (auto p = std::get_if<std::string>(&v)) {
std::cout << "The value is " << *p << std::endl;
}
return 0;
}
在这个示例代码中,我们定义了一个名为 v
的 std::variant
对象,它可以存储 int
、double
和 std::string
三种类型的值。然后,我们分别将 v
赋值为 10
、3.14
和 "hello"
,并使用 std::get
函数获取 v
中的值。接着,我们使用 std::get_if
函数获取 v
中的值的指针,并根据指针的类型输出不同的信息。
总之,std::variant
是一个非常实用的模板类,它可以帮助我们处理多个可能的类型,避免手动使用枚举或联合体。但是,由于它可能会导致类型不匹配或异常,因此在使用时需要格外小心,避免出现不必要的错误。
std::function 与 std::bind函数
std::function
和 std::bind
是 C++11 中引入的两个非常实用的模板类,它们可以帮助我们实现函数对象和函数绑定。下面是一个使用 std::function
和 std::bind
的示例代码:
cpp
#include <iostream>
#include <functional>
void print(int a, int b, int c) {
std::cout << a << " " << b << " " << c << std::endl;
}
int main() {
auto f1 = std::bind(print, 1, 2, 3);
f1();
auto f2 = std::bind(print, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
f2(4, 5, 6);
std::function<void(int, int, int)> f3 = std::bind(print, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
f3(7, 8, 9);
return 0;
}
在这个示例代码中,我们定义了一个名为 print
的函数,它接受三个整数参数,并将它们输出到标准输出流中。然后,我们使用 std::bind
函数创建了两个函数对象 f1
和 f2
,它们分别绑定了 print
函数的三个参数。其中,f1
绑定了具体的参数值 1
、2
和 3
,而 f2
使用了占位符 std::placeholders::_1
、std::placeholders::_2
和 std::placeholders::_3
,表示在调用 f2
时需要传入三个参数。
接着,我们使用 std::function
定义了一个函数对象 f3
,它的类型是 void(int, int, int)
,并将 print
函数绑定到了 f3
上。最后,我们分别调用了 f1
、f2
和 f3
,并传入了不同的参数。
总之,std::function
和 std::bind
是 C++11 中非常实用的模板类,它们可以帮助我们实现函数对象和函数绑定,从而实现更加灵活和高效的编程。在实际开发中,我们可以根据需要灵活地使用它们,提高代码的可读性和可维护性。
std::forward使用
std::forward
是 C++11 中的一个模板函数,它的作用是将一个参数以原始的形式转发给另一个函数。std::forward
通常用于实现完美转发,它可以确保参数以原始的形式传递给其他函数,而不会丢失任何信息或进行不必要的拷贝。
std::forward
的作用是根据参数的类型来选择将其转发为左值引用或右值引用。如果参数是一个左值,那么 std::forward
将返回一个左值引用类型的值,即 T&
。如果参数是一个右值,那么 std::forward
将返回一个右值引用类型的值,即 T&&
。
std::forward
的实现依赖于引用折叠的规则。当我们使用 std::forward
时,我们必须将参数的类型指定为模板参数,以便编译器可以根据参数的类型来推断出正确的引用类型。例如,如果我们要将一个参数 arg
转发给另一个函数,我们可以使用以下代码:
cpp
template<typename T>
void forwarder(T&& arg) {
other_function(std::forward<T>(arg));
}
在这个示例代码中,我们使用了 T&&
作为参数类型,这意味着它可以接受任何类型的参数,包括左值和右值。然后,我们使用 std::forward
函数将参数 arg
以原始的形式转发给另一个函数 other_function
。