Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

value_type of classes with member element_type #299

Closed
CaseyCarter opened this issue Dec 5, 2016 · 7 comments
Closed

value_type of classes with member element_type #299

CaseyCarter opened this issue Dec 5, 2016 · 7 comments

Comments

@CaseyCarter
Copy link
Collaborator

CaseyCarter commented Dec 5, 2016

element_type in std::pointer_traits and in the smart pointers is the type of the object the pointer denotes, not the value type of that object (i.e., it can be a cv-qualified type). The specialization of value_type that uses typename T::element_type should strip cv-qualifiers from the type.

Proposed Resolution:

Modify [iterator.assoc.types.value_type] as follows:

 [...]
 
 2 A Readable type has an associated value type that can be accessed with the value_type_t alias
   template.

     [...]
     template <class T>
       requires requires { typename T::value_type; }
     struct value_type<T>
       : enable_if<is_object<typename T::value_type>::value, typename T::value_type> { };
 
     template <class T>
       requires requires { typename T::element_type; }
     struct value_type<T>
-      : enable_if<is_object<typename T::element_type>::value, typename T::element_type> { };
+      : enable_if<
+          is_object<typename T::element_type>::value,
+          remove_cv_t<typename T::element_type>>
+    { };
 
     template <class T>
       using value_type_t = typename value_type<T>::type;

 [...]

 5 When instantiated with a type I such that I::value_type is valid and denotes a type, [...]
 
 6 When instantiated with a type I such that I::element_type is valid and denotes a type,
-  value_type<I>::type names that type,
+  value_type<I>::type names the type remove_cv_t<I::element_type>,
   unless it is not an object type (ISO/IEC 14882:2014 §3.9)
   in which case value_type<I> shall have no nested type type. [ Note: Smart pointers like
   shared_ptr<int> are Readable and have an associated value type. But a smart pointer like
   shared_ptr<void> is not Readable and has no associated value type.—end note ]
@CaseyCarter
Copy link
Collaborator Author

LWG: Add a note explaining the remove_cv_t for element_type.

@cjdb
Copy link
Contributor

cjdb commented Mar 10, 2017

Did this section move? It's under [iterator.assoc.types.value_type] for me.

@cjdb
Copy link
Contributor

cjdb commented Mar 10, 2017

If not, should it be moved to [iterators.readable]?

@viboes
Copy link

viboes commented Mar 10, 2017

Sorry for the question, but could someone explain why do we need to mix requires clauses with enable_if?
Why the is_object<typename T::value_type>::value is not part of the requires?

@ericniebler
Copy link
Owner

Sorry for the question, but could someone explain why do we need to mix requires clauses with enable_if?

I can imagine a case where it matters:

struct S {
  using value_type = void;
  using element_type = int;
};

Today, this is ambiguous and an error. That's (IMO) a good thing. If we changed the enable_if's to requires for both the value_type and element_type specializations, then the partial specialization for element_type gets selected unambiguously.

I'll grant that this is a fairly contrived example.

@CaseyCarter
Copy link
Collaborator Author

CaseyCarter commented Mar 10, 2017

Another nearly-as-contrived example:

struct foo {
  using value_type = int(float, double);
};

A non-object type cannot be a value type, so ranges::value_type<foo> has no member type.

It might simplify the design overall to keep value_type simple, and filter out garbage by applying constraints like "must be a cv-unqualified object type" to value_type_t.

@CaseyCarter
Copy link
Collaborator Author

Did this section move? It's under [iterator.assoc.types.value_type] for me.

No, must have been a cut'n'paste error in my issue submission. Fixed.

CaseyCarter added a commit to CaseyCarter/cmcstl2 that referenced this issue Jul 2, 2017
CaseyCarter added a commit to CaseyCarter/cmcstl2 that referenced this issue Jul 2, 2017
* Implement ericniebler/stl2#299
* Implement ericniebler/stl2#363
* Implement ericniebler/stl2#364
* Implement ericniebler/stl2#418
* Remove tuple_find that was dropped from variant ages ago
* Implement extension 'structible object concepts
* tighten up constrains in the tagged impl
CaseyCarter pushed a commit that referenced this issue Jul 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants