This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3348. `__cpp_lib_unwrap_ref` in wrong header

Section: 17.3.2 [version.syn], 99 [refwrap.unwrapref] Status: C++20 Submitter: Barry Revzin Opened: 2019-12-03 Last modified: 2021-02-25

Priority: 2

View all other issues in [version.syn].

View all issues with C++20 status.

Discussion:

cpplearner points out in this github comment that:

> Since `unwrap_reference` and `unwrap_ref_decay` are defined in `<functional>` ([functional.syn]), their feature test macro should also be defined there.

P1902R1 adds this feature test macro in `<type_traits>` instead. The feature test macro and the type traits should go into the same header: either both in `<functional>` or both in `<type_traits>`.

The smallest diff is just to move the macro into `<functional>`.

[2019-12-12 Issue Prioritization]

Priority to 2 after reflector discussion.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4842.

> 1. Modify 17.3.2 [version.syn] p2 as indicated:

>    >     […]
>    >     #define __cpp_lib_unordered_map_try_emplace 201411L // also in <unordered_map>
>    >     #define __cpp_lib_unwrap_ref                201811L // also in <type_traitsfunctional>
>    >     #define __cpp_lib_variant                   201606L // also in <variant>
>    >     […]

[2020-02-13, Prague]

During LWG discussions it had been suggested that they considered it is an improvement to move the definitions of `unwrap_reference` and `unwrap_ref_decay` from `<functional>` to `<type_traits>`. This is what the alternative wording tries to accomplish.

[Status to Immediate on Thursday night in Prague.]

Proposed resolution:

This wording is relative to N4849.

1. Modify 20.14.2 [functional.syn], header `<functional>` synopsis, as indicated:

   >     namespace std {
   >     […]
   >     template<class T> struct unwrap_reference;
   >     template<class T> using unwrap_reference_t = typename unwrap_reference<T>::type;
   >     template<class T> struct unwrap_ref_decay;
   >     template<class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
   >     […]
   >     }

2. Delete sub-clause 99 [refwrap.unwrapref] completely, as indicated:

   > 20.14.5.6 Transformation type trait `unwrap_reference` [refwrap.unwrapref]

   >     template<class T>
   >       struct unwrap_reference;

   > > -1- If `T` is a specialization `reference_wrapper<X>` for some type `X`, the member typedef `type` of `unwrap_reference<T>` is `X&`, otherwise it is `T`.

   >     template<class T>
   >       struct unwrap_ref_decay;

   > > -2- The member typedef `type` of `unwrap_ref_decay<T>` denotes the type `unwrap_reference_t<decay_t<T>>`.

3. Modify 20.15.3 [meta.type.synop], header `<type_traits>` synopsis, as indicated:

   >     namespace std {
   >     […]
   >     // 20.15.8.7 [meta.trans.other], other transformations
   >     […]
   >     template<class T> struct underlying_type;
   >     template<class Fn, class... ArgTypes> struct invoke_result;
   >     template<class T> struct unwrap_reference;
   >     template<class T> struct unwrap_ref_decay;

   >     template<class T>
   >       using type_identity_t = typename type_identity<T>::type;
   >     […]
   >     template<class Fn, class... ArgTypes>
   >       using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
   >     template<class T>
   >       using unwrap_reference_t = typename unwrap_reference<T>::type;
   >     template<class T>
   >       using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
   >     template<class...>
   >       using void_t = void;
   >     […]
   >     }

4. Modify 20.15.8.7 [meta.trans.other], Table 55 — "Sign modifications" in [tab:meta.trans.sign] as indicated:

   Table 52 — Other transformations [tab:meta.trans.other]
   Template | Comments
   --- | ---
   `[…]`
   `template <class T> struct unwrap_reference;` | If `T` is a specialization `reference_wrapper<X>` for some type `X`, the member typedef `type` of `unwrap_reference<T>` is `X&`, otherwise it is `T`.
   `template <class T> struct unwrap_ref_decay;` | The member typedef `type` of `unwrap_ref_decay<T>` denotes the type `unwrap_reference_t<decay_t<T>>`.

5. Insert between 20.15.8.7 [meta.trans.other] p1 and p2 as indicated:

   > In addition to being available via inclusion of the `<type_traits>` header, the templates `unwrap_reference`, `unwrap_ref_decay`, `unwrap_reference_t`, and `unwrap_ref_decay_t` are available when the header `<functional>` (20.14.2 [functional.syn]) is included.