<div class="gmail_quote">On Thu, Aug 9, 2012 at 5:48 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote"><div class="im">On Wed, Aug 8, 2012 at 7:41 PM, Michael Price <span dir="ltr"><<a href="mailto:michael.b.price.dev@gmail.com" target="_blank">michael.b.price.dev@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Given two objects, <font face="courier new, monospace">one</font> and <font face="courier new, monospace">two</font> that are references to some pure virtual type <font face="courier new, monospace">MyType</font>, the following code compiles fine:<div>


<br></div><div><div><div><font face="courier new, monospace">    std::pair<std::reference_wrapper<MyType>,std::reference_wrapper<
MyType >> mypair = std::make_pair(std::ref(one), std::ref(two));</font></div><div><font face="courier new, monospace">    std::swap(mypair.first, mypair.second);</font></div></div><div><br></div><div>But if I replace the declaration of the pair object type with 'auto' as in:</div>


<div><br></div><div><div><font face="courier new, monospace">    auto mypair = std::make_pair(std::ref(one), std::ref(two));</font></div></div></div></blockquote><div><br></div></div><div>mypair's type is std::pair<MyType&, MyType&>. See the make_pair specification:</div>

<div><br></div><div><div>template <class T1, class T2> pair<V1, V2> make_pair(T1&& x, T2&& y);</div><div><br></div><div>Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y));</div>

<div>where V1 and V2 are determined as follows: Let Ui be decay<Ti>::type for each Ti. Then each Vi is</div><div>X& if Ui equals reference_wrapper<X>, otherwise Vi is Ui.</div></div><div><br></div></div></blockquote>
<div><br></div><div>So, I guess that std::pair<MyType&, MyType&> is assignable to std::pair<std::reference_wrapper<MyType&>, std::reference_wrapper<MyType&>> then?</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><div></div><div>Then...</div><div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>I get the following errors with std::swap:</div>
</div><div><br></div><div><div><font face="courier new, monospace">GameController.cpp:43:9: error: no matching function for call to 'swap'</font></div><div><font face="courier new, monospace">        std::swap(mypair.first, mypair.second);</font></div>


<div><font face="courier new, monospace">        ^~~~~~~~~</font></div><div><font face="courier new, monospace">/usr/include/c++/v1/type_traits:2902:5: note: candidate template ignored: disabled by 'enable_if' [with _Tp = MyType]</font></div>


<div><font face="courier new, monospace">    is_move_constructible<_Tp>::value &&</font></div><div><font face="courier new, monospace">    ^</font></div></div></blockquote><div><br></div></div><div>your values can't be swapped, because MyType is not move constructible, because it's an abstract class type. The specification for 'swap' says:</div>

<div><br></div><div><div>Requires: Type T shall be MoveConstructible (Table 20) and MoveAssignable (Table 22).</div></div><div><br></div></div></blockquote><div>Why does it compile (and it does in fact appear to execute correctly) if mypair is a pair of reference_wrappers then? I don't think that reference_wrapper is MoveConstrucible and MoveAssignable.</div>
<div><br></div><div>I'm running a pretty recent ToT for both llvm/clang and libcxx on Ubuntu 12.04. Here's the output from running clang++ -v:</div><div><br></div><div><div>clang version 3.2 (<a href="http://llvm.org/git/clang.git">http://llvm.org/git/clang.git</a> b25466e8b33285a13d0303461db37e903ec505c1) (<a href="http://llvm.org/git/llvm">http://llvm.org/git/llvm</a> 913ff09a9acf563ae9719ff223bc117dd66ad6b0)</div>
<div>Target: x86_64-unknown-linux-gnu</div><div>Thread model: posix</div></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote">
<div></div><div>I'm not sure whether it's valid to implement this "Requires:" clause as an enable_if, but in any case, I would expect that better diagnostics would be produced if it were instead a static_assert within the definition of swap.</div>

</div>
</blockquote></div><br>