variant、optional和any 这三个模板类是用来取代C风格的一些不安全的代码
optional —— 持有T或为空
variant<T,U> —— 持有T或U(类似于union)
any —— 持有任意类型(类似于void*)
1 2 3 4 5 6
| std::optional<int> var1 = 7; std::variant<int,string> var2 = 7; std::any var3 = 7; auto x1 = *var1 ; auto x2 = std::get<int>(var2); auto x3 = std::any_cast<int>(var3);
|
variant
std::variant 表示一个类型安全的联合体(变化体)std::variant 的一个实例在任意时刻要么保有它的一个可选类型之一的值,要么在错误情况下无值
1 2 3 4 5 6 7
| union variant{ int, char }
typedef std::variant<int,char> variant;
|
visit
以一或多个 variant 所保有的各实参调用所提供的函数对象
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <cstdio> #include <type_traits> #include <variant> int main() { std::variant<int, char> variant = 1022; std::visit( [](auto &&arg) { if (std::is_same_v<std::decay_t<decltype(arg)>, int>) { printf("variant中存放的是int类型"); } else if (std::is_same_v<std::decay_t<decltype(arg)>, char>) { printf("variant中存放的是char类型"); } }, variant); variant = 'A'; std::visit( [](auto &&arg) { if (std::is_same_v<std::decay_t<decltype(arg)>, int>) { printf("variant中存放的是int类型"); } else if (std::is_same_v<std::decay_t<decltype(arg)>, char>) { printf("variant中存放的是char类型"); } }, variant); }
|
这里只是给出部分示例,因为有些我自己还没看明白,所以后面会更新的
holds_alternative
检查某个 variant 是否当前持有某个给定类型
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <cstdio> #include <variant> int main() { std::variant<int, char> variant = 1022; if (std::holds_alternative<int>(variant)) { printf("%d\n", std::get<int>(variant)); } else if (std::holds_alternative<char>(variant)) { printf("%c\n", std::get<char>(variant)); } variant = 'A'; if (std::holds_alternative<int>(variant)) { printf("%d\n", std::get<int>(variant)); } else if (std::holds_alternative<char>(variant)) { printf("%c\n", std::get<char>(variant)); } }
|
std::get(std::variant)
以给定索引或类型(如果类型唯一)读取 variant 的值,错误时抛出异常
示例
1 2 3 4 5 6 7 8
| #include <cstdio> #include <variant> int main() { std::variant<int, char> variant = 1022; printf("%d\n", std::get<int>(variant)); }
|
optional
std::optional 管理一个可选的容纳值,既可以存在也可以不存在的值
1 2 3 4
| int optional = NULL;
std::optional<int> optional = std::nullopt;
|
has_value
检查对象是否含值
示例
1 2 3 4 5 6 7 8 9
| #include <cstdio> #include <optional> int main() { std::optional<int> optional = std::nullopt; if (!optional.has_value()) { printf("optional为空"); } }
|
any
std::any 描述用于任何可拷贝构造类型的单个值的类型安全容器
1 2 3 4 5
| int value = 10; void *any = &value;
std::any any = 10;
|
has_value
检查对象是否含有值
示例
1 2 3 4 5 6 7 8 9
| #include <any> #include <cstdio> int main() { std::any any = 10; if (any.has_value()) { printf("any不为空\n"); } }
|
type
返回所含值的 typeid
示例
1 2 3 4 5 6 7 8 9
| #include <any> #include <cstdio> int main() { std::any any = 10; if (any.type() == typeid(int)) { printf("any中存放的是int类型\n"); } }
|
any_cast
对被容纳对象的类型安全访问
示例
1 2 3 4 5 6 7 8 9
| #include <any> #include <cstdio> int main() { std::any any = 10; if (any.type() == typeid(int)) { printf("any中存放的是%d\n",std::any_cast<int>(any)); } }
|
目前variant、optional和any的使用也就这么点,后续我还会补充一些我遗漏的内容