Действительно ли конструкция pass-by-value-and-then-move является плохой идиомой?

Так как у нас есть семантика перемещения в C++, в наше время обычно сделать

void set_a(A a) { _a = std::move(a); }

Обоснование - это если a rvalue, копия будет игнорироваться и будет всего одно перемещение.

Но что происходит если a lvalue? Кажется, что будет конструкция копии, и затем присвоение перемещения (принимающий A имеет надлежащий оператор присваивания перемещения). Переместитесь присвоения могут быть дорогостоящими, если объект имеет слишком много членских переменных.

С другой стороны, если мы делаем

void set_a(const A& a) { _a = a; }

Будет всего одно присвоение копии. Мы можем сказать, что этот путь предпочтен по идиоме передачи значением, если мы передадим lvalues?

62
задан 25 December 2018 в 17:30

1 ответ

Удобочитаемость в объявлении:

void foo1( A a ); // easy to read, but unless you see the implementation 
                  // you don't know for sure if a std::move() is used.

void foo2( const A & a ); // longer declaration, but the interface shows
                          // that no copy is required on calling foo().

Производительность:

A a;
foo1( a );  // copy + move
foo2( a );  // pass by reference + copy

Обязанности:

A a;
foo1( a );  // caller copies, foo1 moves
foo2( a );  // foo2 copies

Для типичного встроенного кода обычно нет никакого различия при оптимизации. Но foo2 () мог бы сделать копию только на определенных условиях (например, вставить в карту, если ключ не существует), тогда как для foo1 () копия будет всегда делаться.

0
ответ дан 31 October 2019 в 14:20

Другие вопросы по тегам:

Похожие вопросы: