Search code examples
c++syntaxreferencemove-semantics

Why is std::remove_reference used in std::move?


I tried implementing std::move, which uses std::remove_reference, however it seems to work without it. Please, give me an example in which my implementation will fails whithout std::remove_reference.

template <class type> type && move(type & source) { return (type &&) source; }
template <class type> type && move(type && source) { return (type &&) source; }

Is std::remove_reference used only to avoid overloading std::move?

Here is a test class to help you:

class test {
public :
    test() { }
    test(const test & source) { std::cout << "copy.\n"; }
    test(test && source) { std::cout << "move.\n"; }
};

Not a duplicate of How does std::move() transfer values into RValues? because my question includes an example that seems to show that std::remove_reference is useless in this case + the sub-question.


Solution

  • I tried implementing std::move, which uses std::remove_reference, however it seems to work without it.

    Yes, it is working because you explicitly provided the overload for lvalue reference. While std::remove_reference is only relevant if you are using forwarding references.

    If you take out this line: Godbolt

    template <class type> type && move(type & source) { return (type &&) source; }
    

    And call your function as:

    test t2 = move(t1); //prints copy
    

    To make this work, you will have to use std::remove_reference. Try on Godbolt:

    template <class type>
    std::remove_reference_t<type> && move(type && source)
    {
        return
        static_cast<std::remove_reference_t<type>&& >(source);
    }