Ответ на Powerlord действительно лучший, и я бы порекомендовал еще одно изменение: используйте LIMIT, чтобы убедиться, что db не будет перегружен:
SELECT firstname, lastname, list.address FROM list
INNER JOIN (SELECT address FROM list
GROUP BY address HAVING count(id) > 1) dup ON list.address = dup.address
LIMIT 10
Это хорошая привычка использовать LIMIT, если нет ГДЕ и при создании объединений. Начните с малого значения, проверьте, насколько тяжелен запрос, а затем увеличьте предел.
Однако, что это действительно означает?
Это означает, что, если тип элемента является подвижным, то и тип массива.
std::array<movable, 42> move_from = {...};
std::array<movable, 42> move_to = std::move(move_from); // moves all the elements
Я склонен представлять этот тип как более безопасную версию массива с интерфейсом, совместимым с STL
Не совсем. Это оболочка для массива, обеспечивающая семантику, аналогичную агрегатному классу, включая возможность его копирования и перемещения.
Как
std::array
может двигать-конструировать свои элементы?
Точно так же, как и любой другой агрегат. Его неявный move-constructor будет перемещать-конструировать все его элементы, включая элементы любых массивов элементов.
Можно ли сделать то же самое с обычным массивом?
Только если вы оберните его в тип класса, как это делает std::array
.
Конструктор перемещения по умолчанию для класса (без объединения) выполняет перемещение по элементам. Перемещение элемента данных необработанного массива означает перемещение каждого из элементов массива, см. [Class.copy] / 15.
Следовательно, вы можете переместить необработанный массив, поместив его в класс:
struct wrap
{
std::string arr[25];
};
auto w = wrap();
auto m = std::move(w); // moves the 25 `std::string`s
Вы также можете вручную вызвать конструктор перемещения элементов, например:
std::string a[3] = { /*...*/ };
std::string b[3] = {std::move(a[0]), std::move(a[1]), std::move(a[2])};
Не указывается, если std::array
содержит необработанный массив. Однако он содержит элементы данных из value_type
, поскольку он гарантированно является совокупным. Эти элементы данных будут перемещены, как описано выше, при вызове конструктора перемещения.
Если элементы данных std::array
не являются MoveConstructible, создание экземпляра его конструктора перемещения завершится неудачей.