类模板 std::variant 表示一个类型安全的联合体。 std::variant 的一个实例在任意时刻要么保有其一个可选类型之一的值,要么在错误情况下无值。
std::visit应用观览器 vis 到 variant 变量组 vars 。
std::visit参数:
vis | 接受每个 variant 的每个可能可选项的可调用 (Callable) 对象 |
vars | 传递给观览器的 variant 列表 |
例子1
- 观察器vis针对variant每个可选项必须有之对应的函数,不能缺。
- 返回值是观察器共同返回的类型,不能不一致。
#include <iostream>
#include <variant>
struct Apple { };
struct Orange { };
struct Banana { };
struct Pear { };
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>; // C++20不在需要
int main() {
std::variant<Apple, Orange, Banana, Pear> package = { Banana() };
auto result = std::visit(overload{
[](Apple& ) { std::cout << "Apple\n"; return 1;},
[](Orange& ) { std::cout << "Orange\n"; return 2;},
[](Banana& ) { std::cout << "Banana\n"; return 3;},
[](Pear& ) { std::cout << "Pear\n"; return 4;}
}, package);
std::cout << result << std::endl;
}
例子2
观察器的是多个variant选项笛卡尔积
#include <iostream>
#include <variant>
struct Apple { };
struct Orange { };
struct Banana { };
struct Pear { };
struct Light { };
struct Heavy { };
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>; // C++20不在需要
int main() {
std::variant<Apple, Orange> package1 = { Orange() };
std::variant<Light, Heavy> package2 = { Light() };
auto result = std::visit(overload{
[](Apple&, Light&) { std::cout << "Light Apple\n"; return 1;},
[](Orange&, Light&) { std::cout << "Light Orange\n"; return 2;},
[](Apple&, Heavy&) { std::cout << "Heavy Apple\n"; return 3;},
[](Orange&, Heavy&) { std::cout << "Heavy Orange\n"; return 4;}
}, package1, package2);
std::cout << result << std::endl;
}
https://wandbox.org/nojs/gcc-head
https://wandbox.org/nojs/clang-head
https://wandbox.org/permlink/wyeJ1TNulMwEM6QJ
https://wandbox.org/permlink/qpn9gVjb4vzKja0I