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

### 3541. `indirectly_readable_traits` should be SFINAE-friendly for all types

Section: 23.3.2.2 [readable.traits] Status: WP Submitter: Christopher Di Bella Opened: 2021-04-08 Last modified: 2021-06-07

Priority: Not Prioritized

View all other issues in [readable.traits].

View all issues with WP status.

Discussion:

Following the outcome of LWG 3446, a strict implementation of `std::indirectly_readable_traits` isn't SFINAE-friendly for types that have different `value_type` and `element_type` members due to the ambiguity between the `has-member-value-type` and `has-member-element-type` specialisations. Other traits types are empty when requirements aren't met; we should follow suit here.

[2021-04-20; Reflector poll]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4885.

1. Modify 23.3.2.2 [readable.traits] p1 as indicated:

   >     […]
   >     template<class T>
   >       concept has-member-value-type = requires { typename T::value_type; }; // exposition only

   >     template<class T>
   >       concept has-member-element-type = requires { typename T::element_type; }; // exposition only

   >     template<class> struct indirectly_readable_traits { };

   >     […]

   >     template<has-member-value-type T>
   >     struct indirectly_readable_traits<T>
   >       : cond-value-type<typename T::value_type> { };

   >     template<has-member-element-type T>
   >     struct indirectly_readable_traits<T>
   >       : cond-value-type<typename T::element_type> { };

   >     template<has-member-value-type T>
   >       requires has-member-element-type<T>
   >     struct indirectly_readable_traits<T> { };

   >     template<has-member-value-type T>
   >       requires has-member-element-type<T> &&
   >                same_as<remove_cv_t<typename T::element_type>, remove_cv_t<typename T::value_type>>
   >     struct indirectly_readable_traits<T>
   >       : cond-value-type<typename T::value_type> { };
   >     […]