Переместить std :: string в функцию param - PullRequest
2 голосов
/ 21 марта 2019

Я бы хотел переместить большую строку std :: string в член класса.

А это мой код:

#include <cassert>
#include <string>
#include <iostream>
using namespace std;

class SomeClass {
public:
    void some_method(std::string&& str) {
        my_str = str;
    }

    std::string my_str;
};

int main() {
    SomeClass some_class;

    std::string large_str(100000, 'a');

    some_class.some_method(std::move(large_str));

    assert(large_str.empty());
    assert(!some_class.my_str.empty());
    return 0;
}

Когда после перемещения я ожидаю, что large_str пусто, но этот код не подтвердился в строке assert(large_str.empty()).

Я неправильно понял семантику std::move?

1 Ответ

6 голосов
/ 21 марта 2019

Неужели я неправильно понял семантику std::move?

Отчасти да.Вы забыли преобразовать параметр функции str в значение.В пределах some_method оно снова стало lvalue.Чтобы это исправить:

void some_method(std::string&& str) {
    my_str = std::move(str);
    //       ^^^^^^^^^ Necessary: invoke std::move a 2nd time
}

Но обратите внимание на следующее.std::string объект "Move-from" - это то, что вам не нужно assert здесь , перегрузка # 8 (выделено мной):

Переместить конструктор.Создает строку с содержимым другого, используя семантику перемещения.other остается в допустимом, но неопределенное состояние .

Вы не хотите, чтобы ваша программа зависела от неопределенного состояния (даже если случается, что конкретная реализация делает std::string::size вернуть 0 после потребления его ресурсов).

...