std::visit

来自cppreference.com
< cpp‎ | utility‎ | variant
定义于头文件 <variant>
template <class Visitor, class... Variants>
constexpr /*see below*/ visit(Visitor&& vis, Variants&&... vars);
(C++17 起)

将观览器vis应用到variant变量组vars

等效于返回

std::invoke(std::forward<Visitor>(vis), std::get<is>(std::forward<Variants>(vars))...)

,其中is...vars.index()...

若上述调用不是一个对于所有variant的所有可选项类型均为同一类型和值类别的合法表达式,则调用为病态。

目录

[编辑] 参数

vis - 一个接受每个variant的每个可能可选项的可调用Callable)对象
vars - 传递给观览器的variant列表

[编辑] 返回值

观览器的所选调用所返回的值,转换成所有可行的std::invoke表达式的共用类型。

[编辑] 异常

若任何vars中的variant为因异常无值(valueless_by_exception),则抛出std::bad_variant_access

[编辑] 复杂度

variant的数量为零或一时,可调用对象的调用在常数时间内实现,即它不依赖sizeof...(Types)

variant的数量大于1,则可调用对象的调用没有复杂度要求。

[编辑] 示例

#include <variant>
#include <iostream>
#include <type_traits>
#include <iomanip>
#include <vector>
 
 
template<class T> struct always_false : std::false_type {};
 
using var_t = std::variant<int, long, double, std::string>;
 
int main() {
    std::vector<var_t> vec = {10, 15l, 1.5, "hello"};
    for(auto v: vec) {
        // void观览器,仅为副效应调用
        std::visit([](auto&& arg){std::cout << arg;}, v);
 
        // 值返回观览器:一个常见的惯例是返回另一个variant
        var_t w = std::visit([](auto&& arg) -> var_t {return arg + arg;}, v);
 
        std::cout << ". After doubling, variant holds ";
        // 类型匹配观览器:能同时是一个拥有4个重载的operator()的类
        std::visit([](auto&& arg) {
            using T = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>;
            if constexpr (std::is_same_v<T, int>)
                std::cout << "int with value " << arg << '\n';
            else if constexpr (std::is_same_v<T, long>)
                std::cout << "long with value " << arg << '\n';
            else if constexpr (std::is_same_v<T, double>)
                std::cout << "double with value " << arg << '\n';
            else if constexpr (std::is_same_v<T, std::string>)
                std::cout << "std::string with value " << std::quoted(arg) << '\n';
            else 
                static_assert(always_false<T>::value, "non-exhaustive visitor!");
        }, w);
    }
}

输出:

10. After doubling, variant holds int with value 20
15. After doubling, variant holds long with value 30
1.5. After doubling, variant holds double with value 3
hello. After doubling, variant holds std::string with value "hellohello"

[编辑] 参阅

与另一个variant交换
(公开成员函数) [edit]