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

Michael Price michael.b.price.dev at gmail.com
Thu Aug 9 22:35:18 PDT 2012


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.
> >>
> >> > 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.

Thanks for your help.  I guess it's back to specifying the full type
instead of using the shiny 'auto' keyword.

-- James
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120810/c2bb700d/attachment.html>


More information about the cfe-dev mailing list