127 lines
5.0 KiB
Markdown
127 lines
5.0 KiB
Markdown
[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
|
||
0â¤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.4 Requirements") for the first form and*INVOKE*<R>(std::forward<Visitor>(vis), *GET*<m>(std::forward<V>(vars))...) // see [[func.require]](func.require "22.10.4 Requirements") 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.4 Forward/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.3 Names of template specializations [temp.names]") that
|
||
begins with a type [*template-argument*](temp.names#nt:template-argument "13.3 Names 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.4 Forward/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);
|