2

In the STL implementation of VS10 there is the following code for a variant of std::swap():

    // TEMPLATE FUNCTION _Move
template<class _Ty> inline
    typename tr1::_Remove_reference<_Ty>::_Type&&
        _Move(_Ty&& _Arg)
    {   // forward _Arg as movable
    return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg);
    }

    // TEMPLATE FUNCTION swap (from <algorithm>)
template<class _Ty> inline
    void swap(_Ty& _Left, _Ty& _Right)
    {   // exchange values stored at _Left and _Right
    _Ty _Tmp = _Move(_Left);
    _Left = _Move(_Right);
    _Right = _Move(_Tmp);
    }

The cast to (typename tr1::_Remove_reference<_Ty>::_Type&&) in _Move() is the source of my question.

In this context _Remove_reference is defined as follows:

        // TEMPLATE _Remove_reference
template<class _Ty>
    struct _Remove_reference
    {   // remove reference
    typedef _Ty _Type;
    };

What does _Remove_reference do, and why? Furthermore, what does && do here, and how is it termed?

Michael Smith
  • 403
  • 1
  • 3
  • 8

2 Answers2

3

_Remove_reference is a template that, well, removes the reference from its type. I'm pretty sure that the template is specialized for T& and T&& with the same typedef, right?

Not sure how much I should go into details here. Are you familiar with template metaprogramming?

_Move seems to do exactly what std::move does: it casts its argument to an rvalue. The point of the exercise is that std::swap can do moves instead of copies. Are you familiar with move semantics?

what does && do here, and how is it termed?

The term you are looking for is "rvalue reference". Watch this video and come back with questions.

Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • Very nice thank you. I love it. I read about move semantics, copy-and-swap idiom, and rvalue references. All of which are now crystal clear. Aside from exception safety and code reduction, do you expect there to be performance benefits? – Michael Smith Jan 27 '11 at 20:02
  • To your first twos question; yes you are right, and yes I am familiar with template metaprogramming. – Michael Smith Jan 27 '11 at 20:04
  • @Michael: I'm not sure I understand what you are asking. Are you asking whether moving is faster than copying? That depends on the type. If the type has external resources, then yes, moving is orders of magnitude faster than copying. Think essentially all dynamic STL containers. Moving does *not* offer a performance benefit over copying if the type is "flat", for example `std::array`, because then there are no resources that can be moved by pointer twiddling. Does that answer your question? – fredoverflow Jan 27 '11 at 20:10
  • Yes it answers my question and confirms my thoughts. – Michael Smith Jan 27 '11 at 20:17
  • Also note that in some cases (Visual Studio STL) `std::swap` was already optimized for *move* (there is an specialization of the `std::swap` template that will call the `std::vector<>::swap` method to only interchange the pointers. – David Rodríguez - dribeas Jan 27 '11 at 21:16
1

This is a part of C++0x rvalue references. What the template move does is convert a reference to a rvalue reference so that swap can be implemented with move semantics (no copies are made if the type supports moving.

The _Remove_reference looks like a template that is there to extract a type that has no reference from a type that might have it.

template <typename T> struct remove_ref { typedef T type; };
template <typename T> struct remove_ref<T&> { typedef T type; };
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489