Files
cppdraft_translate/cppdraft/refwrap.md
2025-10-25 03:02:53 +03:00

316 lines
13 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.

[refwrap]
# 22 General utilities library [[utilities]](./#utilities)
## 22.10 Function objects [[function.objects]](function.objects#refwrap)
### 22.10.6 Class template reference_wrapper [refwrap]
#### [22.10.6.1](#general) General [[refwrap.general]](refwrap.general)
[🔗](#lib:reference_wrapper)
namespace std {template<class T> class reference_wrapper {public:// typesusing type = T; // [[refwrap.const]](#const "22.10.6.2Constructors"), constructorstemplate<class U>constexpr reference_wrapper(U&&) noexcept(*see below*); constexpr reference_wrapper(const reference_wrapper& x) noexcept; // [[refwrap.assign]](#assign "22.10.6.3Assignment"), assignmentconstexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept; // [[refwrap.access]](#access "22.10.6.4Access"), accessconstexpr operator T& () const noexcept; constexpr T& get() const noexcept; // [[refwrap.invoke]](#invoke "22.10.6.5Invocation"), invocationtemplate<class... ArgTypes>constexpr invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&...) constnoexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // [[refwrap.comparisons]](#comparisons "22.10.6.6Comparisons"), comparisonsfriend constexpr bool operator==(reference_wrapper, reference_wrapper); friend constexpr bool operator==(reference_wrapper, const T&); friend constexpr bool operator==(reference_wrapper, reference_wrapper<const T>); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); friend constexpr auto operator<=>(reference_wrapper, const T&); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper<const T>); }; template<class T> reference_wrapper(T&) -> reference_wrapper<T>;}
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11697)
reference_wrapper<T> is a [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") and [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2Template argument requirements[utility.arg.requirements]") wrapper
around a reference to an object or function of type T[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11701)
reference_wrapper<T> is
a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1General"))[.](#general-2.sentence-1)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11705)
The template parameter T of reference_wrapper may be an incomplete type[.](#general-3.sentence-1)
[*Note [1](#general-note-1)*:
Using the comparison operators described in [[refwrap.comparisons]](#comparisons "22.10.6.6Comparisons") with T being an incomplete type
can lead to an ill-formed program
with no diagnostic required ([[temp.point]](temp.point "13.8.4.1Point of instantiation"), [[temp.constr.atomic]](temp.constr.atomic "13.5.2.3Atomic constraints"))[.](#general-3.sentence-2)
— *end note*]
#### [22.10.6.2](#const) Constructors [[refwrap.const]](refwrap.const)
[🔗](#lib:reference_wrapper,constructor)
`template<class U>
constexpr reference_wrapper(U&& u) noexcept(see below);
`
[1](#const-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11724)
Let *FUN* denote the exposition-only functionsvoid *FUN*(T&) noexcept;void *FUN*(T&&) = delete;
[2](#const-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11731)
*Constraints*: The expression *FUN*(declval<U>()) is well-formed andis_same_v<remove_cvref_t<U>, reference_wrapper> is false[.](#const-2.sentence-1)
[3](#const-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11736)
*Effects*: Creates a variable r as if by T& r = std::forward<U>(u),
then constructs a reference_wrapper object
that stores a reference to r[.](#const-3.sentence-1)
[4](#const-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11743)
*Remarks*: The exception specification is equivalent tonoexcept(*FUN*(declval<U>()))[.](#const-4.sentence-1)
[🔗](#lib:reference_wrapper,constructor_)
`constexpr reference_wrapper(const reference_wrapper& x) noexcept;
`
[5](#const-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11755)
*Effects*: Constructs a reference_wrapper object that
stores a reference to x.get()[.](#const-5.sentence-1)
#### [22.10.6.3](#assign) Assignment [[refwrap.assign]](refwrap.assign)
[🔗](#lib:operator=,reference_wrapper)
`constexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept;
`
[1](#assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11769)
*Postconditions*: *this stores a reference to x.get()[.](#assign-1.sentence-1)
#### [22.10.6.4](#access) Access [[refwrap.access]](refwrap.access)
[🔗](#lib:operator_T&,reference_wrapper)
`constexpr operator T& () const noexcept;
`
[1](#access-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11782)
*Returns*: The stored reference[.](#access-1.sentence-1)
[🔗](#lib:get,reference_wrapper)
`constexpr T& get() const noexcept;
`
[2](#access-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11793)
*Returns*: The stored reference[.](#access-2.sentence-1)
#### [22.10.6.5](#invoke) Invocation [[refwrap.invoke]](refwrap.invoke)
[🔗](#lib:operator(),reference_wrapper)
`template<class... ArgTypes>
constexpr invoke_result_t<T&, ArgTypes...>
operator()(ArgTypes&&... args) const noexcept(is_nothrow_invocable_v<T&, ArgTypes...>);
`
[1](#invoke-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11808)
*Mandates*: T is a complete type[.](#invoke-1.sentence-1)
[2](#invoke-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11812)
*Returns*: *INVOKE*(get(), std::forward<ArgTypes>(args)...) ([[func.require]](func.require "22.10.4Requirements"))[.](#invoke-2.sentence-1)
#### [22.10.6.6](#comparisons) Comparisons [[refwrap.comparisons]](refwrap.comparisons)
[🔗](#comparisons-itemdecl:1)
`friend constexpr bool operator==(reference_wrapper x, reference_wrapper y);
`
[1](#comparisons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11824)
*Constraints*: The expression x.get() == y.get() is well-formed and
its result is convertible to bool[.](#comparisons-1.sentence-1)
[2](#comparisons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11829)
*Returns*: x.get() == y.get()[.](#comparisons-2.sentence-1)
[🔗](#comparisons-itemdecl:2)
`friend constexpr bool operator==(reference_wrapper x, const T& y);
`
[3](#comparisons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11839)
*Constraints*: The expression x.get() == y is well-formed and
its result is convertible to bool[.](#comparisons-3.sentence-1)
[4](#comparisons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11844)
*Returns*: x.get() == y[.](#comparisons-4.sentence-1)
[🔗](#comparisons-itemdecl:3)
`friend constexpr bool operator==(reference_wrapper x, reference_wrapper<const T> y);
`
[5](#comparisons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11854)
*Constraints*: is_const_v<T> is false and
the expression x.get() == y.get() is well-formed and
its result is convertible to bool[.](#comparisons-5.sentence-1)
[6](#comparisons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11860)
*Returns*: x.get() == y.get()[.](#comparisons-6.sentence-1)
[🔗](#comparisons-itemdecl:4)
`friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper y);
`
[7](#comparisons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11870)
*Constraints*: The expression *synth-three-way*(x.get(), y.get()) is well-formed[.](#comparisons-7.sentence-1)
[8](#comparisons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11875)
*Returns*: *synth-three-way*(x.get(), y.get())[.](#comparisons-8.sentence-1)
[🔗](#comparisons-itemdecl:5)
`friend constexpr auto operator<=>(reference_wrapper x, const T& y);
`
[9](#comparisons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11885)
*Constraints*: The expression *synth-three-way*(x.get(), y) is well-formed[.](#comparisons-9.sentence-1)
[10](#comparisons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11890)
*Returns*: *synth-three-way*(x.get(), y)[.](#comparisons-10.sentence-1)
[🔗](#comparisons-itemdecl:6)
`friend constexpr auto operator<=>(reference_wrapper x, reference_wrapper<const T> y);
`
[11](#comparisons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11900)
*Constraints*: is_const_v<T> is false[.](#comparisons-11.sentence-1)
The expression *synth-three-way*(x.get(), y.get()) is well-formed[.](#comparisons-11.sentence-2)
[12](#comparisons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11906)
*Returns*: *synth-three-way*(x.get(), y.get())[.](#comparisons-12.sentence-1)
#### [22.10.6.7](#helpers) Helper functions [[refwrap.helpers]](refwrap.helpers)
[1](#helpers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11913)
The template parameter T of
the following ref and cref function templates
may be an incomplete type[.](#helpers-1.sentence-1)
[🔗](#lib:ref,reference_wrapper)
`template<class T> constexpr reference_wrapper<T> ref(T& t) noexcept;
`
[2](#helpers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11924)
*Returns*: reference_wrapper<T>(t)[.](#helpers-2.sentence-1)
[🔗](#lib:ref,reference_wrapper_)
`template<class T> constexpr reference_wrapper<T> ref(reference_wrapper<T> t) noexcept;
`
[3](#helpers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11935)
*Returns*: t[.](#helpers-3.sentence-1)
[🔗](#lib:cref,reference_wrapper)
`template<class T> constexpr reference_wrapper<const T> cref(const T& t) noexcept;
`
[4](#helpers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11946)
*Returns*: reference_wrapper<const T>(t)[.](#helpers-4.sentence-1)
[🔗](#lib:cref,reference_wrapper_)
`template<class T> constexpr reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
`
[5](#helpers-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11957)
*Returns*: t[.](#helpers-5.sentence-1)
#### [22.10.6.8](#common.ref) common_reference related specializations [[refwrap.common.ref]](refwrap.common.ref)
[🔗](#lib:basic_common_reference)
namespace std {template<class T>constexpr bool *is-ref-wrapper* = false; // *exposition only*template<class T>constexpr bool *is-ref-wrapper*<reference_wrapper<T>> = true; template<class R, class T, class RQ, class TQ>concept [*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8common_­reference related specializations[refwrap.common.ref]") = // *exposition only**is-ref-wrapper*<R> &&requires { typename common_reference_t<typename R::type&, TQ>; } &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<RQ, common_reference_t<typename R::type&, TQ>>; template<class R, class T, template<class> class RQual, template<class> class TQual>requires ([*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8common_­reference related specializations[refwrap.common.ref]")<R, T, RQual<R>, TQual<T>> &&![*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8common_­reference related specializations[refwrap.common.ref]")<T, R, TQual<T>, RQual<R>>)struct basic_common_reference<R, T, RQual, TQual> {using type = common_reference_t<typename R::type&, TQual<T>>; }; template<class T, class R, template<class> class TQual, template<class> class RQual>requires ([*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8common_­reference related specializations[refwrap.common.ref]")<R, T, RQual<R>, TQual<T>> &&![*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8common_­reference related specializations[refwrap.common.ref]")<T, R, TQual<T>, RQual<R>>)struct basic_common_reference<T, R, TQual, RQual> {using type = common_reference_t<typename R::type&, TQual<T>>; };}