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

Ahmed Charles acharles at outlook.com
Fri Aug 10 11:50:13 PDT 2012


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/ba32ebbc/attachment.html>


More information about the cfe-dev mailing list