[cfe-dev] Broken type deduction for pair of reference_wrappers?

Michael Price - Dev michael.b.price.dev at gmail.com
Fri Aug 10 12:06:19 PDT 2012


Ah, yes, I jumped the gun when I saw && and delete in the same signature. I believe you are correct and it makes more sense now.

Sent from my iPhone

On Aug 10, 2012, at 1:50 PM, Ahmed Charles <acharles at outlook.com> wrote:

> The deleted constructor is from T&&, so it is not a move constructor, but just a regular one.
> 
> The MoveConstructible and MoveAssignable requirements are designed to allow the standard containers to be specified. Thus, having move as a superset of copy makes sense and allows for less verbosity without loosing too much clarity. It is also the case that attempting to move something that only has copy operations will work, since copy constructors accept a superset of what move constructors accept.
> 
> The standard is right, it's just a matter of communication and understanding. Though I'm not sure if I've explained clearly enough yet.
> From: James Dennett
> Sent: 8/9/2012 11:37 PM
> To: Michael Price
> Cc: Richard Smith; Clang Developers List
> Subject: Re: [cfe-dev] Broken type deduction for pair of reference_wrappers?
> 
> On Thu, Aug 9, 2012 at 10:35 PM, Michael Price
> <michael.b.price.dev at gmail.com> wrote:
> >
> > On Thu, Aug 9, 2012 at 11:48 PM, James Dennett <james.dennett at gmail.com>
> > wrote:
> >>
> >> On Thu, Aug 9, 2012 at 9:41 PM, Michael Price
> >> <michael.b.price.dev at gmail.com> wrote:
> >> > On Thu, Aug 9, 2012 at 10:02 PM, James Dennett <james.dennett at gmail.com>
> >> > wrote:
> >> >>
> >> >> On Thu, Aug 9, 2012 at 7:16 PM, Michael Price
> >> >> <michael.b.price.dev at gmail.com> wrote:
> >> >> > On Thu, Aug 9, 2012 at 5:48 PM, Richard Smith <richard at metafoo.co.uk>
> >> >> > wrote:
> >>
> > <SNIP>
> >>
> >> >> >>
> >> >> >> your values can't be swapped, because MyType is not move
> >> >> >> constructible,
> >> >> >> because it's an abstract class type. The specification for 'swap'
> >> >> >> says:
> >> >> >>
> >> >> >> Requires: Type T shall be MoveConstructible (Table 20) and
> >> >> >> MoveAssignable
> >> >> >> (Table 22).
> >> >> >>
> >> >> > Why does it compile (and it does in fact appear to execute correctly)
> >> >> > if
> >> >> > mypair is a pair of reference_wrappers then?
> >> >>
> >> >> Because reference_wrapper is CopyConstructible and CopyAssignable
> >> >> (hence MoveConstructible and MoveAssignable), which is why it's a good
> >> >> match for what std::pair needs.
> 
> In hindsight: The standard makes this claim, but I think it's wrong.
> 
> >> >> > I don't think that
> >> >> > reference_wrapper is MoveConstrucible and MoveAssignable.
> >> >>
> >> >> Why not?
> >> >
> >> > The following web page mentions CopyConstructible and CopyAssignable,
> >> > but
> >> > not the move equivalents (granted, it is not authoritative).
> >> > http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
> >> >
> >> > Why would copyable imply movable? You can definitely have types that are
> >> > copyable but not movable as they can be deleted independently.
> >>
> >> The standard specifies the requirements for CopyConstructible and
> >> CopyAssignable as refinements of  MoveConstructible and MoveAssignable
> >> respectively (see tables 20-23).
> >>
> > 20.8.3 Class template reference_wrapper [refwrap]
> >
> > namespace std {
> >   template <class T> class reference_wrapper {
> >   public :
> > ...
> >     // construct/copy/destroy
> >     reference_wrapper(T&) noexcept;
> >     reference_wrapper(T&&) = delete; // do not bind to temporary objects
> >     reference_wrapper(const reference_wrapper<T>& x) noexcept;
> >     // assignment
> >     reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
> > ...
> >   };
> > }
> >
> > Clearly that thing cannot be move constructed.  Maybe we are talking past
> > each other at this point.  I feel that I still don't quite understand how a
> > type could be considered MoveConstructible, yet have a deleted move
> > constructor, but I'm willing to chalk that up to language-lawyer-ese.
> 
> You have a point, and I think that this is a defect in the standard.
> reference_wrapper is documented as being
> CopyConstructible/CopyAssignable, but it is not.  CopyConstructible
> implies MoveConstructible which implies that construction from an
> rvalue is permitted, but reference_wrapper disables that, so it's not
> MoveConstructible and hence no longer meets the CopyConstructible
> requirements (though its predecessor did in a world before move
> semantics).
> 
> > Thanks for your help.  I guess it's back to specifying the full type instead
> > of using the shiny 'auto' keyword.
> 
> Yes, if the special-casing of reference wrapper is getting in your way
> then that's the way around it.
> 
> -- James
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120810/44e969f7/attachment.html>


More information about the cfe-dev mailing list