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

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


On Thu, Aug 9, 2012 at 5:48 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> On Wed, Aug 8, 2012 at 7:41 PM, Michael Price <
> michael.b.price.dev at gmail.com> wrote:
>
>> Given two objects, one and two that are references to some pure virtual
>> type MyType, the following code compiles fine:
>>
>>     std::pair<std::reference_wrapper<MyType>,std::reference_wrapper<
>> MyType >> mypair = std::make_pair(std::ref(one), std::ref(two));
>>     std::swap(mypair.first, mypair.second);
>>
>> But if I replace the declaration of the pair object type with 'auto' as
>> in:
>>
>>     auto mypair = std::make_pair(std::ref(one), std::ref(two));
>>
>
> mypair's type is std::pair<MyType&, MyType&>. See the make_pair
> specification:
>
> template <class T1, class T2> pair<V1, V2> make_pair(T1&& x, T2&& y);
>
> Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y));
> where V1 and V2 are determined as follows: Let Ui be decay<Ti>::type for
> each Ti. Then each Vi is
> X& if Ui equals reference_wrapper<X>, otherwise Vi is Ui.
>
>
So, I guess that std::pair<MyType&, MyType&> is assignable to
std::pair<std::reference_wrapper<MyType&>, std::reference_wrapper<MyType&>>
then?


> Then...
>
>
>> I get the following errors with std::swap:
>>
>> GameController.cpp:43:9: error: no matching function for call to 'swap'
>>         std::swap(mypair.first, mypair.second);
>>         ^~~~~~~~~
>> /usr/include/c++/v1/type_traits:2902:5: note: candidate template ignored:
>> disabled by 'enable_if' [with _Tp = MyType]
>>     is_move_constructible<_Tp>::value &&
>>     ^
>>
>
> 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? I don't think that
reference_wrapper is MoveConstrucible and MoveAssignable.

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:

clang version 3.2
(http://llvm.org/git/clang.gitb25466e8b33285a13d0303461db37e903ec505c1)
(
http://llvm.org/git/llvm 913ff09a9acf563ae9719ff223bc117dd66ad6b0)
Target: x86_64-unknown-linux-gnu
Thread model: posix



> 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.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120809/d7487cdd/attachment.html>


More information about the cfe-dev mailing list