8

Given this example:

 std::vector<std::string> split(const std::string& str) {
    std::vector<std::string> result;
    std::string curr;
    for (auto c : str) {
        if (c == DELIMITER) {
            result.push_back(std::move(curr)); // ATTENTION HERE!
        } else {
            curr.push_back(c);
        }
    }
    result.push_back(std::move(curr));
    return result;
}

Can I reuse the curr std:string? This snippet seems working: after curr is moved inside the result vector, it becomes empty. I want to be sure this is not an undefined behavior in the standard and it isn't working only because of luck.

Alessandro Pezzato
  • 8,603
  • 5
  • 45
  • 63

3 Answers3

14

With a few exceptions (smart pointers, for instance), moved-from objects are left in a valid but unspecified state.

In a std::string that uses the small string optimization, for instance, if the string is small, there is no dynamic allocation, and a move is a copy. In that case it is perfectly valid for the implementation to leave the source string untouched, and not incur the extra cost of emptying the string.

T.C.
  • 133,968
  • 17
  • 288
  • 421
4

May be, this link will be useful

In short, for reuse you need to call .clear method

Community
  • 1
  • 1
RainLabs
  • 41
  • 1
1

From http://en.cppreference.com/w/cpp/utility/move

...all standard library functions that accept rvalue reference parameters (such as std::vector::push_back) are guaranteed to leave the moved-from argument in valid but unspecified state.

Neska
  • 110
  • 4