std::visit
提供: cppreference.com
ヘッダ <variant> で定義
|
||
template <class Visitor, class... Variants> constexpr /*see below*/ visit(Visitor&& vis, Variants&&... vars); |
(1) | (C++17以上) |
template <class R, class Visitor, class... Variants> constexpr R visit(Visitor&&, Variants&&...); |
(2) | (C++20以上) |
ビジター vis
をバリアント vars
に適用します。
実質的に
std::invoke(std::forward<Visitor>(vis), std::get<is>(std::forward<Variants>(vars))...)
を返します。 ただし is...
は vars.index()...
です。
1) 戻り値の型は decltype によって行われたかのように返される式から推定されます。 すべての variant の選択肢型��すべての組み合わせについて、上記の呼び出しが同じ型および値カテゴリの有効な式でなければ、この呼び出しは ill-formed です。
2) 戻り値の型は
R
です。 R
が void (または cv 修飾された void) の場合、 invoke
式の結果は破棄されます。目次 |
[編集] 引数
vis | - | すべての variant からのすべての可能な選択肢を受理する Callable |
vars | - | ビジターに渡す variant のリスト |
[編集] 戻り値
1) ビジターの選択された呼び出しによって返された値。
2)
R
が void (または cv 修飾された void) の場合は、なし。 そうでなければ、ビジターの選択された呼び出しによって返された値が R
に暗黙に変換された値。[編集] 例外
vars
内のいずれかの variant が valueless_by_exception の場合、 std::bad_variant_access を投げます。
[編集] 計算量
variant の数が0または1のとき、 callable オブジェクトの呼び出しは定数時間で実装されます。 つまり sizeof...(Types)
に依存しません。
variant の数が1より大きいとき、 callable オブジェクトの呼び出しに計算量の要件はありません。
[編集] 例
Run this code
#include <iomanip> #include <iostream> #include <string> #include <type_traits> #include <variant> #include <vector> // visit するバリアント。 using var_t = std::variant<int, long, double, std::string>; // ビジター #3 のためのヘルパー型。 template<class T> struct always_false : std::false_type {}; // ビジター #4 のためのヘルパー型。 template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; int main() { std::vector<var_t> vec = {10, 15l, 1.5, "hello"}; for(auto& v: vec) { // 1. void ビジター。 副作用 (ここでは入出力) のためだけに呼ばれます。 std::visit([](auto&& arg){std::cout << arg;}, v); // 2. 値を返すビジター。 別のバリアントを返すイディオムをデモンストレーションします。 var_t w = std::visit([](auto&& arg) -> var_t {return arg + arg;}, v); // 3. 型マッチングビジター。 それぞれの型に対して異なる処理をするラムダ。 std::cout << ". After doubling, variant holds "; std::visit([](auto&& arg) { using T = std::decay_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); } for (auto& v: vec) { // 4. 別の型マッチングビジター。 オーバーロードされた3つの operator() を持つクラス。 std::visit(overloaded { [](auto arg) { std::cout << arg << ' '; }, [](double arg) { std::cout << std::fixed << arg << ' '; }, [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; }, }, v); } }
出力:
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" 10 15 1.500000 "hello"
[編集] 関連項目
別の variant と交換します (パブリックメンバ関数) |