Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

move семантика до 11 стандарта

#cpp #cpp98


Как поместить в data_new объект data_old без копирования последнего, т.е. переместить
его? Стандарт 98.

Data foo() {
    Data data_old;
    //...
    return data_old;
}

int main() {
    Data data_new = foo();
}

    


Ответы

Ответ 1



Использовать оптимизацию не ниже -O1 и полагаться на copy elision — конструирование объекта прямо на области стека для data_new. Оптимизация возможна благодаря компиляции возврата сложных типов в передачу функции неявного параметра-указателя на переменную, принимающую результат. Пример: struct Foo {int a;}; Foo bar(int a) { Foo result; result.a = a; return result; } void baz() { Foo field = bar(12); } Без оптимизаций это будет выглядеть на низком уровне примерно так: struct Foo {int a;}; void __cdecl bar(Foo* __out, int a) { Foo result; result.a = a; new(__out) Foo(result); // Вызов конструктора копирования } void __cdecl baz() { Foo field; bar(&field, 12); } С copy elision bar станет таким: void __cdecl bar(Foo* __out, int a) { __out->a = a; }

Ответ 2



В качестве дополнения. Можно вспомнить, что костылем для семантики перемещения до C++11 был auto_ptr, и сыграть с ним... ...но замечу, что Мейерс в "Эффективном и современном C++" рекомендовал не полагаться на перемещение при возврате из функции. Так что постарайтесь, чтобы не было нескольких путей возврата из функции, и возвращался один объект - этого должно быть достаточно для оптимизации. И еще - на всякий случай: Data foo() { Data data_old(); //... return data_old; } В первой строке у вас - объявление функции data_old. Надеюсь, это опечатка только в вопросе.

Комментариев нет:

Отправить комментарий