indirectly_readable_traits
ambiguity for types with both value_type
and element_type
Section: 24.3.2.2 [readable.traits] Status: C++23 Submitter: Casey Carter Opened: 2020-05-15 Last modified: 2023-11-22
Priority: 2
View all other issues in [readable.traits].
View all issues with C++23 status.
Discussion:
Per 24.3.2.2 [readable.traits], indirectly_readable_traits<T>::value_type
is the same type as
remove_cv_t<T::value_type>
if it denotes an object type, or remove_cv_t<T::element_type>
if it denotes an object type. If both T::value_type
and T::element_type
denote types,
indirectly_readable_traits<T>::value_type
is ill-formed. This was perhaps not the best design,
given that there are iterators in the wild (Boost's unordered containers) that define both nested types.
indirectly_readable_traits
should tolerate iterators that define both nested types consistently.
[2020-07-17; Priority set to 2 in telecon]
Previous resolution [SUPERSEDED]:This wording is relative to N4861.
Modify 24.3.2.2 [readable.traits] as indicated:
[…] template<class> struct cond-value-type { }; // exposition only template<class T> requires is_object_v<T> struct cond-value-type<T> { using value_type = remove_cv_t<T>; }; template<class> struct indirectly_readable_traits { }; […] template<class T> requires requires { typename T::value_type; } struct indirectly_readable_traits<T> : cond-value-type<typename T::value_type> { }; template<class T> requires requires { typename T::element_type; } struct indirectly_readable_traits<T> : cond-value-type<typename T::element_type> { }; template<class T> requires requires { typename T::element_type; typename T::value_type; requires 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> { }; […]
[2020-07-23; Casey improves wording per reflector discussion]
[2020-08-21; moved to Tentatively Ready after five votes in favour in reflector poll]
[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]
Proposed resolution:
This wording is relative to N4861.
Modify 24.3.2.2 [readable.traits] as indicated:
[…] template<class> struct cond-value-type { }; // exposition only template<class T> requires is_object_v<T> struct cond-value-type<T> { using value_type = remove_cv_t<T>; }; 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<classhas-member-value-type T>requires requires { typename T::value_type; }struct indirectly_readable_traits<T> : cond-value-type<typename T::value_type> { }; template<classhas-member-element-type T>requires requires { typename T::element_type; }struct indirectly_readable_traits<T> : cond-value-type<typename T::element_type> { }; template<classhas-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> { }; […]