Как использовать переменную и перемещать переменную одновременно? - PullRequest
3 голосов
/ 15 марта 2020

Давайте предположим, что у нас есть следующий код:

struct some_class : parent
{

    some_class(::other_class oth) :
       parent(some_function(oth.some_property), std::move(oth))
    {}

};

Конечно, конструирование приводит к неопределенному поведению (cra sh в моем случае), поскольку c ++ не определяет порядок выполнения. Но тогда, как я могу получить имущество до движения? Я не могу сменить родителя.

Ответы [ 3 ]

3 голосов
/ 15 марта 2020

Создайте вспомогательную функцию для создания родительского элемента, в который вы можете добавить последовательность:

parent make_parent(::other_class &&oth) {
    auto sf = some_function(oth.some_property);
    return parent(sf, std::move(oth));
}

some_class(::other_class oth) :
    parent(make_parent(std::move(oth))
{}
1 голос
/ 15 марта 2020

Как вы заметили, проблема связана с неопределенным порядком исполнения. Вы можете избавиться от неопределенного поведения, заставив parent взять объект по ссылке rvalue вместо lvalue. Таким образом он получает ссылку на существующий объект, и данные этого объекта в памяти фактически не будут перемещены. Т.е.:

struct parent {
   parent (int thing, SomeProperty && some_property) { /* Do stuff. */ }
};

В этом случае не имеет значения, когда std::move выполняется на oth. Эти данные фактически не будут перемещены в другой объект, так как parent ожидает ссылку на значение. Таким образом, даже если std::move вызывается первым, ваш some_function (который, как я предполагаю, принимает oth по ссылке на константное значение) будет иметь подходящий объект для работы.

Основной недостаток здесь тот родитель теперь всегда требует в rvalue. Таким образом, вы не можете передать ему объект, не перемещая его. Это означает, что если у вас есть объект, от которого вы не хотите избавляться, вам сначала нужно явно сделать его копию. Т.е.:

other_class wantToKeepThis;
auto foo = parent(wantToKeepThis); // Doesn't compile.
auto foo = parent(std::move(wantToKeepThis)); // Object gone, don't want this.
auto foo = parent(other_class(wantToKeepThis)); // OK, copied, parent gets rvalue.
0 голосов
/ 15 марта 2020

Вы можете попробовать делегирующий конструктор:

struct some_class : parent
{

    some_class(::other_class oth) :
       some_class(some_function(oth.some_property), std::move(oth))
    {}

private:
    some_class(const ::Foo& foo, ::other_class&& oth) :
       parent(foo, std::move(oth))
    {}
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...