С++ 11 use-case для кусочной_конструкции пары и кортежа?
В N3059 я нашел описание кусочной конструкции пар (и кортежей) (и он находится в новом стандарте).
Но я не вижу, когда я должен его использовать. Я нашел обсуждения об элементах emplace и non-copyable, но когда я попробовал это, я не смог создать случай, когда мне нужно piecewiese_construct
или вы могли бы увидеть преимущество производительности.
Пример. Я думал, что мне нужен класс, который не копируется, но movebale (требуется для пересылки):
struct NoCopy {
NoCopy(int, int) {};
NoCopy(const NoCopy&) = delete; // no copy
NoCopy& operator=(const NoCopy&) = delete; // no assign
NoCopy(NoCopy&&) {}; // please move
NoCopy& operator=(NoCopy&&) {}; // please move-assign
};
Затем я отчасти ожидал, что стандартная пара-конструкция завершится неудачно:
pair<NoCopy,NoCopy> x{ NoCopy{1,2}, NoCopy{2,3} }; // fine!
но это не так. На самом деле, это то, чего я ожидал в любом случае, потому что "перемещение вокруг", а не копирование его повсюду в stdlib, должно быть.
Таким образом, я не вижу причин, почему я должен был это сделать или так:
pair<NoCopy,NoCopy> y(
piecewise_construct,
forward_as_tuple(1,2),
forward_as_tuple(2,3)
); // also fine
- Итак, что такое usecase?
- Как и когда использовать
piecewise_construct
?
Ответы
Ответ 1
Не все типы могут перемещаться более эффективно, чем скопировать, и для некоторых типов может иметь смысл даже явно отключить как копирование, так и перемещение. Рассмотрим std::array<int, BIGNUM>
как пример первого типа типа.
Точка с функциями emplace
и piecewise_construct
заключается в том, что такой класс можно построить на месте, без необходимости создавать временные экземпляры для перемещения или копирования.
struct big {
int data[100];
big(int first, int second) : data{first, second} {
// the rest of the array is presumably filled somehow as well
}
};
std::pair<big, big> pair(piecewise_construct, {1,2}, {3,4});
Сравните приведенное выше с pair(big(1,2), big(3,4))
, где должны быть созданы два временных объекта big
, а затем скопированы - и перемещение вообще не помогает! Аналогично:
std::vector<big> vec;
vec.emplace_back(1,2);
Основной прецедент для кусочного построения пары - это размещение элементов в map
или unordered_map
:
std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});