Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::visit

      From cppreference.com
      <cpp‎ |utility‎ |variant
       
       
      Utilities library
       
       
      Defined in header<variant>
      template<class Visitor,class...Variants>
      constexpr/* see below */ visit( Visitor&& v, Variants&&...values);
      (1)(since C++17)
      template<class R,class Visitor,class...Variants>
      constexpr R visit( Visitor&& v, Variants&&...values);
      (2)(since C++20)
      Helper templates
      template<class...Ts>
      auto&& as-variant(std::variant<Ts...>& value);
      (3)(exposition only*)
      template<class...Ts>
      auto&& as-variant(conststd::variant<Ts...>& value);
      (4)(exposition only*)
      template<class...Ts>
      auto&& as-variant(std::variant<Ts...>&& value);
      (5)(exposition only*)
      template<class...Ts>
      auto&& as-variant(conststd::variant<Ts...>&& value);
      (6)(exposition only*)

      Applies the visitorv (aCallable that can be called with any combination of types from Variants) to the Variantsvalues.

      GivenVariantBases asdecltype(as-variant(std::forward<Variants>(values))... (a pack ofsizeof...(Variants) types):

      1) Invokesv as if by

      INVOKE(std::forward<Visitor>(v),
             std::get<indices>(std::forward<VariantBases>(values))...)
      ,

      whereindices isas-variant(values).index()....
      2) Invokesv as if by

      INVOKE<R>(std::forward<Visitor>(v),
                std::get<indices>(std::forward<VariantBases>(values))...)
      ,

      whereindices isas-variant(values).index()....

      These overloads participate in overload resolution only if every type inVariantBases is a valid type. If the expression denoted byINVOKE orINVOKE<R>(since C++20) is invalid, or the results ofINVOKE orINVOKE<R>(since C++20) have different types or value categories for differentindices, the program is ill-formed.

      3-6) The exposition-onlyas-variant function templates accept a value whose type can bededuced forstd::variant<Ts...> (i.e., eitherstd::variant<Ts...> or a type derived fromstd::variant<Ts...>), and return thestd::variant value with the same const-qualification and value category.
      3,4) Returnsvalue.
      5,6) Returnsstd::move(value).

      Contents

      [edit]Parameters

      v - aCallable that accepts every possible alternative from every variant inVariants
      values - list of variants to pass to the visitor

      [edit]Return value

      1) The result of theINVOKE operation. The return type is the type obtained from applyingdecltype to the result.
      2) Nothing ifR is (possibly cv-qualified)void; otherwise the result of theINVOKE<R> operation.
      3-6) Astd::variant value converted fromvalue.

      [edit]Exceptions

      Throwsstd::bad_variant_access ifas-variant(value_i).valueless_by_exception() istrue for any variantvalue_i invalues.

      [edit]Complexity

      When the number of variants is zero or one, the invocation of the callable object is implemented in constant time; i.e., it does not depend on the number of types can be stored in the variant.

      If the number of variants is larger than one, the invocation of the callable object has no complexity requirements.

      [edit]Notes

      Letn be(1* ...*std::variant_size_v<std::remove_reference_t<VariantBases>>), implementations usually generate a table equivalent to an (possibly multidimensional) array ofn function pointers for every specialization ofstd::visit, which is similar to the implementation ofvirtual functions.

      Implementations may also generate aswitch statement withn branches forstd::visit (e.g., the MSVC STL implementation uses a switch statement whenn is not greater than 256).

      On typical implementations, the time complexity of the invocation ofv can be considered equal to that of access to an element in an (possibly multidimensional) array or execution of a switch statement.

      Feature-test macroValueStdFeature
      __cpp_lib_variant202102L(C++23)
      (DR17)
      std::visit for classes derived fromstd::variant

      [edit]Example

      Run this code
      #include <iomanip>#include <iostream>#include <string>#include <type_traits>#include <variant>#include <vector> // the variant to visitusing value_t=std::variant<int,long,double,std::string>; // helper type for the visitor #4template<class...Ts>struct overloaded: Ts...{using Ts::operator()...;};// explicit deduction guide (not needed as of C++20)template<class...Ts>overloaded(Ts...)-> overloaded<Ts...>; int main(){std::vector<value_t> vec={10,15l,1.5,"hello"}; for(auto& v: vec){// 1. void visitor, only called for side-effects (here, for I/O)std::visit([](auto&& arg){std::cout<< arg;}, v); // 2. value-returning visitor, demonstrates the idiom of returning another variant        value_t w=std::visit([](auto&& arg)-> value_t{return arg+ arg;}, v); // 3. type-matching visitor: a lambda that handles each type differentlystd::cout<<". After doubling, variant holds ";std::visit([](auto&& arg){using T=std::decay_t<decltype(arg)>;ifconstexpr(std::is_same_v<T,int>)std::cout<<"int with value "<< arg<<'\n';elseifconstexpr(std::is_same_v<T,long>)std::cout<<"long with value "<< arg<<'\n';elseifconstexpr(std::is_same_v<T,double>)std::cout<<"double with value "<< arg<<'\n';elseifconstexpr(std::is_same_v<T,std::string>)std::cout<<"std::string with value "<<std::quoted(arg)<<'\n';else                static_assert(false,"non-exhaustive visitor!");}, w);} for(auto& v: vec){// 4. another type-matching visitor: a class with 3 overloaded operator()'s// Note: The `(auto arg)` template operator() will bind to `int` and `long`//       in this case, but in its absence the `(double arg)` operator()//       *will also* bind to `int` and `long` because both are implicitly//       convertible to double. When using this form, care has to be taken//       that implicit conversions are handled correctly.std::visit(overloaded{[](auto arg){std::cout<< arg<<' ';},[](double arg){std::cout<<std::fixed<< arg<<' ';},[](conststd::string& arg){std::cout<<std::quoted(arg)<<' ';}}, v);}}

      Output:

      10. After doubling, variant holds int with value 2015. After doubling, variant holds long with value 301.5. After doubling, variant holds double with value 3hello. After doubling, variant holds std::string with value "hellohello"10 15 1.500000 "hello"

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 2970C++17the return type of overload(1) did not preserve the
      value category of the result of theINVOKE operation
      preserves
      LWG 3052
      (P2162R2)
      C++17the effects were unspecified if any type
      inVariants is not astd::variant
      specified

      [edit]See also

      (C++26)
      calls the provided functor with the argument held by thevariant
      (public member function)[edit]
      swaps with anothervariant
      (public member function)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/utility/variant/visit2&oldid=181214"

      [8]ページ先頭

      ©2009-2025 Movatter.jp