You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Many people have commented on the oddness of using enable_if in the specification of value_type in [iterator.assoc.types.value_type] (shown here after applying #299):
The reason for the use of enable_if in e.g. the element_type case is simple to explain: we want this specialization to be used when T has a member type element_type even if it specifies a non-object type so that value_type_t<T> is properly ambiguous for a T that specifies both element_type and value_type. Nonetheless, many readers' first reaction is confusion: "I thought Concepts meant not having to use enable_if anymore?!?" It would reduce reader confusion to eliminate the metaprogramming and use only associated constraints in the definition of value_type.
Further, the specification of value_type is deliberately ambiguous when the type T has both a member type value_type and a member type element_type: the idea here is that the implementer of T should specialize value_type explicitly to disambiguate. I speculate that there is a sizable body of types in the wild with implementers that are confused about whether they should specify value_type or element_type that simply give up and specify both (e.g., the proposed span view which seems to think it's a container and a smart pointer). There's no reason that value_type should refuse to admit such types when the value_type and element_type they specify are consistent.
Finally, the text description of value_type is confused and redundant:
Para 3 "The value_type class template may be specialized on user-defined types." normatively duplicates the allowance in the blanket wording in C++14 [namespace.std].
Paras 4 "When instantiated with a type I such that I::value_type is valid and denotes a type, value_type<I>::type names that type, unless it is not an object type..." and 5 "When instantiated with a type I such that I::element_type is valid and denotes a type, value_type<I>::type names that type, unless it is not an object type..." redundantly specify requirements that are already explicit in the definition in para 1.
Proposed Resolution
[Editor's note: This wording incorporates the PR of #299. We present two alternatives here: #1 ignores element_type when value_type is present, and #2 requires the two to be consistent when both are present.]
Replace the specification of value_type in [iterator.assoc.types.value_type]/1 with:
For both alternatives, also replace paragraphs 3 through 5 with:
3 [Note: Pursuant to the requirements of ISO/IEC 14882:2014 §\cxxref{namespace.std} users may specialize value_type to specify the associated value type of a user-defined type.—end note]
4 [Note: Some legacy output iterators define a nested type value_type that is an alias for void. These types are not Readable and have no associated value types.—end note]
5 [Note: Smart pointers like shared_ptr<int> are Readable and have an associated value type. A smart pointer like shared_ptr<void>, however, has no associated value type and is therefore not Readable.—end note]
[Editor's note: Consider replacing uses of I in this section that refer to a type that potentially has an associated value type with T. Use of I is appropriate for types that satisfy Iterator, but value_type
has applicability beyond models of iterator. ]
The text was updated successfully, but these errors were encountered:
I don't love the added complexity here. I would be ok with just picking T::value_type over T::element_type, with a de facto requirement that they be the same when they are both present.
I would be ok with just picking T::value_type over T::element_type, with a de facto requirement that they be the same when they are both present.
I've included alternative wording for that formulation in the PR. (I have a mild preference to tell users they're making a mistake by defining conflicting value_type and element_type, we'll see what LWG has to say if and when we get around to discussing P4s.)
Many people have commented on the oddness of using
enable_if
in the specification ofvalue_type
in [iterator.assoc.types.value_type] (shown here after applying #299):The reason for the use of
enable_if
in e.g. theelement_type
case is simple to explain: we want this specialization to be used whenT
has a member typeelement_type
even if it specifies a non-object type so thatvalue_type_t<T>
is properly ambiguous for aT
that specifies bothelement_type
andvalue_type
. Nonetheless, many readers' first reaction is confusion: "I thought Concepts meant not having to useenable_if
anymore?!?" It would reduce reader confusion to eliminate the metaprogramming and use only associated constraints in the definition ofvalue_type
.Further, the specification of
value_type
is deliberately ambiguous when the typeT
has both a member typevalue_type
and a member typeelement_type
: the idea here is that the implementer ofT
should specializevalue_type
explicitly to disambiguate. I speculate that there is a sizable body of types in the wild with implementers that are confused about whether they should specifyvalue_type
orelement_type
that simply give up and specify both (e.g., the proposedspan
view which seems to think it's a container and a smart pointer). There's no reason thatvalue_type
should refuse to admit such types when thevalue_type
andelement_type
they specify are consistent.Finally, the text description of
value_type
is confused and redundant:value_type
class template may be specialized on user-defined types." normatively duplicates the allowance in the blanket wording in C++14 [namespace.std].I
such thatI::value_type
is valid and denotes a type,value_type<I>::type
names that type, unless it is not an object type..." and 5 "When instantiated with a typeI
such thatI::element_type
is valid and denotes a type,value_type<I>::type
names that type, unless it is not an object type..." redundantly specify requirements that are already explicit in the definition in para 1.Proposed Resolution
[Editor's note: This wording incorporates the PR of #299. We present two alternatives here: #1 ignores
element_type
whenvalue_type
is present, and #2 requires the two to be consistent when both are present.]Replace the specification of
value_type
in [iterator.assoc.types.value_type]/1 with:For alternative 1 (
value_type
takes precedence overelement_type
) further append:For alternative 2 (
value_type
andelement_type
must be consistent) instead append:For both alternatives, also replace paragraphs 3 through 5 with:
[Editor's note: Consider replacing uses of
I
in this section that refer to a type that potentially has an associated value type withT
. Use ofI
is appropriate for types that satisfyIterator
, butvalue_type
has applicability beyond models of iterator. ]
The text was updated successfully, but these errors were encountered: