Files
2025-10-25 03:02:53 +03:00

127 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[variant.visit]
# 22 General utilities library [[utilities]](./#utilities)
## 22.6 Variants [[variant]](variant#visit)
### 22.6.7 Visitation [variant.visit]
[🔗](#lib:visit)
`template<class Visitor, class... Variants>
constexpr see below visit(Visitor&& vis, Variants&&... vars);
template<class R, class Visitor, class... Variants>
constexpr R visit(Visitor&& vis, Variants&&... vars);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6802)
Let *as-variant* denote the following exposition-only function templates:template<class... Ts>constexpr auto&& *as-variant*(variant<Ts...>& var) { return var; }template<class... Ts>constexpr auto&& *as-variant*(const variant<Ts...>& var) { return var; }template<class... Ts>constexpr auto&& *as-variant*(variant<Ts...>&& var) { return std::move(var); }template<class... Ts>constexpr auto&& *as-variant*(const variant<Ts...>&& var) { return std::move(var); }
Let n be sizeof...(Variants)[.](#1.sentence-2)
For each 0≤i<n, letVi denote the type
decltype(*as-variant*(std::forward<Variantsi>(varsi)))[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6819)
*Constraints*: Vi is a valid type for all 0≤i<n[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6823)
Let V denote the pack of types Vi[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6826)
Let m be a pack of n values of type size_t[.](#4.sentence-1)
Such a pack is valid if
‰¤mi<variant_size_v<remove_reference_t<Vi>> for all 0≤i<n[.](#4.sentence-2)
For each valid pack m, let e(m) denote the expression:*INVOKE*(std::forward<Visitor>(vis), *GET*<m>(std::forward<V>(vars))...) // see [[func.require]](func.require "22.10.4Requirements") for the first form and*INVOKE*<R>(std::forward<Visitor>(vis), *GET*<m>(std::forward<V>(vars))...) // see [[func.require]](func.require "22.10.4Requirements") for the second form[.](#4.sentence-3)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6841)
*Mandates*: For each valid pack m, e(m) is a valid expression[.](#5.sentence-1)
All such expressions are of the same type and value category[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6846)
*Returns*: e(m), where m is the pack for whichmi is *as-variant*(varsi).index() for all 0≤i<n[.](#6.sentence-1)
The return type is decltype(e(m)) for the first form[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6853)
*Throws*: bad_variant_access if(*as-variant*(vars).valueless_by_exception() || ...) is true[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6859)
*Complexity*: For n ≤ 1, the invocation of the callable object is
implemented in constant time, i.e., for n=1, it does not depend on
the number of alternative types of V0[.](#8.sentence-1)
For n>1, the invocation of the callable object has
no complexity requirements[.](#8.sentence-2)
[🔗](#lib:visit,variant_)
`template<class Self, class Visitor>
constexpr decltype(auto) visit(this Self&& self, Visitor&& vis);
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6875)
Let V be*OVERRIDE_REF*(Self&&, *COPY_CONST*(remove_reference_t<Self>, variant)) ([[forward]](forward "22.2.4Forward/move helpers"))[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6879)
*Constraints*: The call to visit does not use
an explicit [*template-argument-list*](temp.names#nt:template-argument-list "13.3Names of template specializations[temp.names]") that
begins with a type [*template-argument*](temp.names#nt:template-argument "13.3Names of template specializations[temp.names]")[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6885)
*Effects*: Equivalent to: return std::visit(std::forward<Visitor>(vis), (V)self);
[🔗](#lib:visit,variant__)
`template<class R, class Self, class Visitor>
constexpr R visit(this Self&& self, Visitor&& vis);
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6897)
Let V be*OVERRIDE_REF*(Self&&, *COPY_CONST*(remove_reference_t<Self>, variant)) ([[forward]](forward "22.2.4Forward/move helpers"))[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6901)
*Effects*: Equivalent to: return std::visit<R>(std::forward<Visitor>(vis), (V)self);