std::variant
是 C++17 引入的一个类型安全的联合体(union),它允许你在一系列类型中存储单一的值。std::visit
是一个函数模板,它允许你以一种类型安全的方式访问 std::variant
中存储的值。
使用可变模板(variadic templates)对 std::variant
进行访问,通常是指使用 std::visit
函数配合 lambda 表达式或者重载函数对象来实现多态行为。
以下是一个简单的例子,展示了如何使用 std::visit
和可变模板来访问 std::variant
中的值:
#include <iostream>
#include <variant>
// 假设我们有一个 std::variant,它可以存储 int 或者 std::string 类型的值
using VarType = std::variant<int, std::string>;
// 访问者类,用于处理不同类型的值
struct Visitor {
void operator()(int i) const {
std::cout << "Visiting int: "<< i << std::endl;
}
void operator()(const std::string& s) const {
std::cout << "Visiting string: "<< s << std::endl;
}
};
int main() {
// 创建一个 std::variant 实例
VarType var = 42;
// 使用 std::visit 和 Visitor 来访问 variant 中的值
std::visit(Visitor{}, var);
// 修改 variant 中的值
var = std::string("Hello, World!");
// 再次使用 std::visit 访问新值
std::visit(Visitor{}, var);
return 0;
}
在这个例子中,Visitor
是一个函数对象,它重载了 operator()
来处理 int
和 std::string
类型的值。std::visit
函数接受一个 Visitor
实例和一个 VarType
实例,然后调用相应的 operator()
来处理 variant
中存储的值。
如果你想使用 lambda 表达式来实现类似的功能,可以这样做:
#include <iostream>
#include <variant>
using VarType = std::variant<int, std::string>;
int main() {
VarType var = 42;
// 使用 lambda 表达式作为访问者
std::visit([](const auto& value) {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, int>) {
std::cout << "Visiting int: " << value << std::endl;
} else if constexpr (std::is_same_v<T, std::string>) {
std::cout << "Visiting string: " << value << std::endl;
}
}, var);
var = std::string("Hello, World!");
std::visit([](const auto& value) {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, int>) {
std::cout << "Visiting int: " << value << std::endl;
} else if constexpr (std::is_same_v<T, std::string>) {
std::cout << "Visifying string: " << value << std::endl;
}
}, var);
return 0;
}
在这个例子中,lambda 表达式使用了 auto
关键字和 decltype
来推断值的类型,并使用 if constexpr
来进行编译时的类型判断和处理。
这两种方法都可以实现对 std::variant
中存储值的安全访问,并且可以根据需要灵活地扩展以处理更多的类型。
领取专属 10元无门槛券
手把手带您无忧上云