std visit
std::visit
std::visit 使得variant可以使用类似函数重载的条用模式:
std::visit
是 C++17 引入的一个非常强大的工具,用于处理 std::variant
(变体类型)中的数据。它允许你对 std::variant
中存储的不同类型的数据执行不同的操作,而无需手动检查类型。以下是 std::visit
的几种常见用法:
1. 使用对象函数方式访问
你可以定义一个访问者类,为每种可能的类型提供一个 operator()
函数。然后,使用 std::visit
调用相应的函数。
示例代码:
#include <iostream>
#include <variant>
#include <string>struct MyVisitor {void operator()(double d) const {std::cout << d << '\n';}void operator()(int i) const {std::cout << i << '\n';}void operator()(const std::string& s) const {std::cout << s << '\n';}
};int main() {std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");std::visit(MyVisitor(), var1);std::visit(MyVisitor(), var2);std::visit(MyVisitor(), var3);return 0;
}
2. 使用泛型 Lambda 表达式访问
std::visit
也可以与泛型 Lambda 表达式一起使用,这使得代码更加简洁。
示例代码:
#include <iostream>
#include <variant>
#include <string>auto printvariant = [](const auto& val) {std::cout << val << std::endl;
};int main() {std::variant<int, double, std::string> var1(42), var2(3.14), var3("visit");std::visit(printvariant, var1);std::visit(printvariant, var2);std::visit(printvariant, var3);return 0;
}
3. 使用重载的 Lambda 表达式访问
你可以定义一组 Lambda 表达式,并使用 std::visit
来选择最适合当前类型的 Lambda。
示例代码:
#include <iostream>
#include <variant>
#include <string>template<typename... Ts>
struct overload : Ts... {using Ts::operator()...;
};template<typename... Ts>
overload(Ts...) -> overload<Ts...>;int main() {std::variant<int, std::string> var(42);std::visit(overload{[](int i) { std::cout << "int: " << i << '\n'; },[](const std::string& s) { std::cout << "string: " << s << '\n'; },}, var);return 0;
}
4. 多个 std::variant
的访问
std::visit
还可以同时处理多个 std::variant
,这在处理多个可能的类型组合时非常有用。
示例代码:
#include <iostream>
#include <variant>
#include <string>struct LightItem {};
struct HeavyItem {};int main() {std::variant<LightItem, HeavyItem> basicPackA;std::variant<LightItem, HeavyItem> basicPackB;std::visit(overload{[](LightItem&, LightItem&) { std::cout << "2 light items\n"; },[](LightItem&, HeavyItem&) { std::cout << "light & heavy items\n"; },[](HeavyItem&, LightItem&) { std::cout << "heavy & light items\n"; },[](HeavyItem&, HeavyItem&) { std::cout << "2 heavy items\n"; },}, basicPackA, basicPackB);return 0;
}