[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.2 Constructors"), constructorstemplate<class U>constexpr 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"), invocationtemplate<class... ArgTypes>constexpr invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&...) constnoexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // [[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<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.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<T> 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<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.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<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.8 common_­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.4 Concept 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.8 common_­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.8 common_­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.8 common_­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.8 common_­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>>; };}
