<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div>
<div style="font-family: Calibri,sans-serif; font-size: 11pt;">The deleted constructor is from T&&, so it is not a move constructor, but just a regular one.<br>
<br>
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.<br>
<br>
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.<br>
</div>
</div>
<hr>
<span style="font-family: Tahoma,sans-serif; font-size: 10pt; font-weight: bold;">From:
</span><span style="font-family: Tahoma,sans-serif; font-size: 10pt;">James Dennett</span><br>
<span style="font-family: Tahoma,sans-serif; font-size: 10pt; font-weight: bold;">Sent:
</span><span style="font-family: Tahoma,sans-serif; font-size: 10pt;">8/9/2012 11:37 PM</span><br>
<span style="font-family: Tahoma,sans-serif; font-size: 10pt; font-weight: bold;">To:
</span><span style="font-family: Tahoma,sans-serif; font-size: 10pt;">Michael Price</span><br>
<span style="font-family: Tahoma,sans-serif; font-size: 10pt; font-weight: bold;">Cc:
</span><span style="font-family: Tahoma,sans-serif; font-size: 10pt;">Richard Smith; Clang Developers List</span><br>
<span style="font-family: Tahoma,sans-serif; font-size: 10pt; font-weight: bold;">Subject:
</span><span style="font-family: Tahoma,sans-serif; font-size: 10pt;">Re: [cfe-dev] Broken type deduction for pair of reference_wrappers?</span><br>
<br>
<div class="BodyFragment"><font size="2"><span style="font-size:10pt;">
<div class="PlainText">On Thu, Aug 9, 2012 at 10:35 PM, Michael Price<br>
<michael.b.price.dev@gmail.com> wrote:<br>
><br>
> On Thu, Aug 9, 2012 at 11:48 PM, James Dennett <james.dennett@gmail.com><br>
> wrote:<br>
>><br>
>> On Thu, Aug 9, 2012 at 9:41 PM, Michael Price<br>
>> <michael.b.price.dev@gmail.com> wrote:<br>
>> > On Thu, Aug 9, 2012 at 10:02 PM, James Dennett <james.dennett@gmail.com><br>
>> > wrote:<br>
>> >><br>
>> >> On Thu, Aug 9, 2012 at 7:16 PM, Michael Price<br>
>> >> <michael.b.price.dev@gmail.com> wrote:<br>
>> >> > On Thu, Aug 9, 2012 at 5:48 PM, Richard Smith <richard@metafoo.co.uk><br>
>> >> > wrote:<br>
>><br>
> <SNIP><br>
>><br>
>> >> >><br>
>> >> >> your values can't be swapped, because MyType is not move<br>
>> >> >> constructible,<br>
>> >> >> because it's an abstract class type. The specification for 'swap'<br>
>> >> >> says:<br>
>> >> >><br>
>> >> >> Requires: Type T shall be MoveConstructible (Table 20) and<br>
>> >> >> MoveAssignable<br>
>> >> >> (Table 22).<br>
>> >> >><br>
>> >> > Why does it compile (and it does in fact appear to execute correctly)<br>
>> >> > if<br>
>> >> > mypair is a pair of reference_wrappers then?<br>
>> >><br>
>> >> Because reference_wrapper is CopyConstructible and CopyAssignable<br>
>> >> (hence MoveConstructible and MoveAssignable), which is why it's a good<br>
>> >> match for what std::pair needs.<br>
<br>
In hindsight: The standard makes this claim, but I think it's wrong.<br>
<br>
>> >> > I don't think that<br>
>> >> > reference_wrapper is MoveConstrucible and MoveAssignable.<br>
>> >><br>
>> >> Why not?<br>
>> ><br>
>> > The following web page mentions CopyConstructible and CopyAssignable,<br>
>> > but<br>
>> > not the move equivalents (granted, it is not authoritative).<br>
>> > <a href="http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper">
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper</a><br>
>> ><br>
>> > Why would copyable imply movable? You can definitely have types that are<br>
>> > copyable but not movable as they can be deleted independently.<br>
>><br>
>> The standard specifies the requirements for CopyConstructible and<br>
>> CopyAssignable as refinements of  MoveConstructible and MoveAssignable<br>
>> respectively (see tables 20-23).<br>
>><br>
> 20.8.3 Class template reference_wrapper [refwrap]<br>
><br>
> namespace std {<br>
>   template <class T> class reference_wrapper {<br>
>   public :<br>
> ...<br>
>     // construct/copy/destroy<br>
>     reference_wrapper(T&) noexcept;<br>
>     reference_wrapper(T&&) = delete; // do not bind to temporary objects<br>
>     reference_wrapper(const reference_wrapper<T>& x) noexcept;<br>
>     // assignment<br>
>     reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;<br>
> ...<br>
>   };<br>
> }<br>
><br>
> Clearly that thing cannot be move constructed.  Maybe we are talking past<br>
> each other at this point.  I feel that I still don't quite understand how a<br>
> type could be considered MoveConstructible, yet have a deleted move<br>
> constructor, but I'm willing to chalk that up to language-lawyer-ese.<br>
<br>
You have a point, and I think that this is a defect in the standard.<br>
reference_wrapper is documented as being<br>
CopyConstructible/CopyAssignable, but it is not.  CopyConstructible<br>
implies MoveConstructible which implies that construction from an<br>
rvalue is permitted, but reference_wrapper disables that, so it's not<br>
MoveConstructible and hence no longer meets the CopyConstructible<br>
requirements (though its predecessor did in a world before move<br>
semantics).<br>
<br>
> Thanks for your help.  I guess it's back to specifying the full type instead<br>
> of using the shiny 'auto' keyword.<br>
<br>
Yes, if the special-casing of reference wrapper is getting in your way<br>
then that's the way around it.<br>
<br>
-- James<br>
_______________________________________________<br>
cfe-dev mailing list<br>
cfe-dev@cs.uiuc.edu<br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</div>
</span></font></div>
</body>
</html>