Comment by HarHarVeryFunny

Comment by HarHarVeryFunny 13 hours ago

9 replies

Well, no, because CAN take isn't the same as WILL take.

Changing something to an rvalue means it'll now match a move constructor, but there is no guarantee a move constructor will be used, even if defined, because you've got classes like std::vector that are picky and are explicitly looking for a noexcept move constructor.

fluoridation 12 hours ago

In that sense, std::move() is no different than other passing semantics. Just because you wrote at the call site that you want to pass a copy of your object doesn't mean that the callee will actually make a copy of it.

  • HarHarVeryFunny 12 hours ago

    I'm not sure what you are saying.

    If we have foo(std::string a, std string b), and then call it like this:

    std::string x;

    std::string y;

    foo(std::move(x), y);

    Then x will be moved into a, and y will be copied into b.

    The callee has no say in this - it's just the compiler implementing the semantics of the language.

    • fluoridation 10 hours ago

      Who says there's only one resolution candidate? A different overload could be defined elsewhere that the compiler prefers for that particular combination of arguments, that doesn't cause a copy. std::move() works the same way. The semantics of the operation is defined not by what's at the call site, but by the context.

      • HarHarVeryFunny 10 hours ago

        Sure overload resolution happens first, but once the compiler has found the correct match then the way arguments are passed depends only on the function signature of that match (callee), and how the caller is passing.

        An argument passed to a value parameter will be passed by copying, unless it's an rvalue (e.g. forced with std:move) where a move constructor has been defined for that type, in which case it will be moved. The callee has no say in this.