[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 reference_wrapper {public:// typesusing type = T; // [[refwrap.const]](#const "22.10.6.2 Constructors"), constructorstemplateconstexpr reference_wrapper(U&&) noexcept(*see below*); constexpr reference_wrapper(const reference_wrapper& x) noexcept; // [[refwrap.assign]](#assign "22.10.6.3 Assignment"), assignmentconstexpr reference_wrapper& operator=(const reference_wrapper& x) noexcept; // [[refwrap.access]](#access "22.10.6.4 Access"), accessconstexpr operator T& () const noexcept; constexpr T& get() const noexcept; // [[refwrap.invoke]](#invoke "22.10.6.5 Invocation"), invocationtemplateconstexpr invoke_result_t operator()(ArgTypes&&...) constnoexcept(is_nothrow_invocable_v); // [[refwrap.comparisons]](#comparisons "22.10.6.6 Comparisons"), comparisonsfriend constexpr bool operator==(reference_wrapper, reference_wrapper); friend constexpr bool operator==(reference_wrapper, const T&); friend constexpr bool operator==(reference_wrapper, reference_wrapper); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); friend constexpr auto operator<=>(reference_wrapper, const T&); friend constexpr auto operator<=>(reference_wrapper, reference_wrapper); }; template reference_wrapper(T&) -> reference_wrapper;} [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11697) reference_wrapper is a [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template 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 is a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General"))[.](#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.6 Comparisons") with T being an incomplete type can lead to an ill-formed program with no diagnostic required ([[temp.point]](temp.point "13.8.4.1 Point of instantiation"), [[temp.constr.atomic]](temp.constr.atomic "13.5.2.3 Atomic constraints"))[.](#general-3.sentence-2) — *end note*] #### [22.10.6.2](#const) Constructors [[refwrap.const]](refwrap.const) [🔗](#lib:reference_wrapper,constructor) `template 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()) is well-formed andis_same_v, 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), 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()))[.](#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 constexpr invoke_result_t operator()(ArgTypes&&... args) const noexcept(is_nothrow_invocable_v); ` [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(args)...) ([[func.require]](func.require "22.10.4 Requirements"))[.](#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 y); ` [5](#comparisons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11854) *Constraints*: is_const_v 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 y); ` [11](#comparisons-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11900) *Constraints*: is_const_v 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 constexpr reference_wrapper ref(T& t) noexcept; ` [2](#helpers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11924) *Returns*: reference_wrapper(t)[.](#helpers-2.sentence-1) [🔗](#lib:ref,reference_wrapper_) `template constexpr reference_wrapper ref(reference_wrapper 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 constexpr reference_wrapper cref(const T& t) noexcept; ` [4](#helpers-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L11946) *Returns*: reference_wrapper(t)[.](#helpers-4.sentence-1) [🔗](#lib:cref,reference_wrapper_) `template constexpr reference_wrapper cref(reference_wrapper 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 {templateconstexpr bool *is-ref-wrapper* = false; // *exposition only*templateconstexpr bool *is-ref-wrapper*> = true; templateconcept [*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_­reference related specializations [refwrap.common.ref]") = // *exposition only**is-ref-wrapper* &&requires { typename common_reference_t; } &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")>; template class RQual, template class TQual>requires ([*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_­reference related specializations [refwrap.common.ref]"), TQual> &&![*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_­reference related specializations [refwrap.common.ref]"), RQual>)struct basic_common_reference {using type = common_reference_t>; }; template class TQual, template class RQual>requires ([*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_­reference related specializations [refwrap.common.ref]"), TQual> &&![*ref-wrap-common-reference-exists-with*](#concept:ref-wrap-common-reference-exists-with "22.10.6.8 common_­reference related specializations [refwrap.common.ref]"), RQual>)struct basic_common_reference {using type = common_reference_t>; };}