<div class="gmail_quote">On Thu, Aug 9, 2012 at 10:02 PM, James Dennett <span dir="ltr"><<a href="mailto:james.dennett@gmail.com" target="_blank">james.dennett@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Thu, Aug 9, 2012 at 7:16 PM, Michael Price<br>
<div class="im"><<a href="mailto:michael.b.price.dev@gmail.com">michael.b.price.dev@gmail.com</a>> wrote:<br>
> On Thu, Aug 9, 2012 at 5:48 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
>><br>
>> On Wed, Aug 8, 2012 at 7:41 PM, Michael Price<br>
>> <<a href="mailto:michael.b.price.dev@gmail.com">michael.b.price.dev@gmail.com</a>> wrote:<br>
>>><br>
>>> Given two objects, one and two that are references to some pure virtual<br>
>>> type MyType, the following code compiles fine:<br>
>>><br>
>>>     std::pair<std::reference_wrapper<MyType>,std::reference_wrapper<<br>
>>> MyType >> mypair = std::make_pair(std::ref(one), std::ref(two));<br>
>>>     std::swap(mypair.first, mypair.second);<br>
>>><br>
>>> But if I replace the declaration of the pair object type with 'auto' as<br>
>>> in:<br>
>>><br>
>>>     auto mypair = std::make_pair(std::ref(one), std::ref(two));<br>
>><br>
>><br>
>> mypair's type is std::pair<MyType&, MyType&>. See the make_pair<br>
>> specification:<br>
>><br>
>> template <class T1, class T2> pair<V1, V2> make_pair(T1&& x, T2&& y);<br>
>><br>
>> Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y));<br>
>> where V1 and V2 are determined as follows: Let Ui be decay<Ti>::type for<br>
>> each Ti. Then each Vi is<br>
>> X& if Ui equals reference_wrapper<X>, otherwise Vi is Ui.<br>
>><br>
><br>
> So, I guess that std::pair<MyType&, MyType&> is assignable to<br>
> std::pair<std::reference_wrapper<MyType&>, std::reference_wrapper<MyType&>><br>
> then?<br>
<br>
</div>Given that reference_wrapper<T> is implicitly constructible from T&<br>
(though not T&&), yes.<br>
<div class="im"><br>
>><br>
>> Then...<br>
>><br>
>>><br>
>>> I get the following errors with std::swap:<br>
>>><br>
>>> GameController.cpp:43:9: error: no matching function for call to 'swap'<br>
>>>         std::swap(mypair.first, mypair.second);<br>
>>>         ^~~~~~~~~<br>
>>> /usr/include/c++/v1/type_traits:2902:5: note: candidate template ignored:<br>
>>> disabled by 'enable_if' [with _Tp = MyType]<br>
>>>     is_move_constructible<_Tp>::value &&<br>
>>>     ^<br>
>><br>
>><br>
>> your values can't be swapped, because MyType is not move constructible,<br>
>> because it's an abstract class type. The specification for 'swap' says:<br>
>><br>
>> Requires: Type T shall be MoveConstructible (Table 20) and MoveAssignable<br>
>> (Table 22).<br>
>><br>
> Why does it compile (and it does in fact appear to execute correctly) if<br>
> mypair is a pair of reference_wrappers then?<br>
<br>
</div>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>
<div class="im"><br>
> I don't think that<br>
> reference_wrapper is MoveConstrucible and MoveAssignable.<br>
<br>
</div>Why not?<br></blockquote><div>The following web page mentions CopyConstructible and CopyAssignable, but not the move equivalents (granted, it is not authoritative). <a href="http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper">http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper</a></div>
<div> </div><div>Why would copyable imply movable? You can definitely have types that are copyable but not movable as they can be deleted independently. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<span class="HOEnZb"><font color="#888888"><br>
-- James<br>
</font></span></blockquote></div><br>