Почему мне нужно вызвать std :: move для временного динамического набора битов?

Я рассказываю здесь длинную историю, потому что, в дополнение к прямому ответу, я хотел бы знать, были ли мои рассуждения, которые привели к этой ситуации, правильными.

У меня есть функция, принимающая dynamic_bitset<> аргумент (от Boost.dynamic_bitset).
Скажи, что это выглядит так.

void foo(boost::dynamic_bitset<> db) {
// do stuff
}

Бывает так, что он вызывается только с временными файлами, построенными из конструктора, как в foo(boost::dynamic_bitset<>{5}.set()) (для вызова с 5-битным набором битов со всеми установленными битами).

Мои наборы битов имеют только небольшое количество битов (менее 32). Поэтому сначала я подумал: «Я просто передам это по значению; копия меньше указателя». Но потом я подумал: «Он динамический, поэтому должен выделять пространство в куче. Я хочу избежать ненужных выделений и освобождений»

Итак, я мог бы сделать это

void foo(const boost::dynamic_bitset<>& db);

Но ссылка — это указатель, а dynamic_bitset (предположительно) имеет указатель на свои данные, поэтому затем используем db в foo будет проходить через два уровня косвенности, которая кажется глупой. Очевидно, что лучшим способом было бы скопировать указатель на данные в foo, без перераспределения и копирования данных в кучу.

«Ага!» Я говорю. «Конечно, для этого и нужна семантика перемещения». Итак, я меняю подпись на

void foo(boost::dynamic_bitset<>&& db);

Но потом, звоня foo(boost::dynamic_bitset<>{5}.set()) выдает ошибку компилятора, cannot bind 'boost::dynamic_bitset<>' lvalue to 'boost::dynamic_bitset<>&&',
Я должен вместо этого позвонить
foo(std::move(boost::dynamic_bitset<>{5}.set()))
и тогда все работает.

Почему мне нужно вызывать std :: move?
Похоже, что это явно значение xvalue (временно истекающее), не так ли?

4

Решение

От ускоренные документы:

dynamic_bitset& set();

set() возвращает lvalue.

В общем случае, если функция возвращает значение или ссылку на rvalue:

dynamic_bitset   set();
dynamic_bitset&& set();

тогда выражение set() является rvalue (в первом случае prvalue, а во втором xvalue). Однако, потому что в реальном коде set() возвращает ссылку на lvalue, выражение set() это значение.

значения категорий http://downloads.sehe.nl/stackoverflow/value-categories.svg

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]