Я занят тестированием реализации различных общих алгоритмов, и я использую типы с минимальной поддержкой предоставленных функций. Я столкнулся с этой странной установкой при использовании std::pair<T, movable>
с типом T
(например, int
) и movable
, определенным следующим образом:
struct movable
{
movable() {}
movable(movable&&) = default;
// movable(movable const&) = delete;
movable(movable&) = delete;
};
Идея имеет тип, который можно перемещать, но не копировать. Это отлично работает, например, с такими выражениями:
movable m1 = movable();
movable m2 = std::move(m1);
Однако при попытке использовать этот тип в качестве члена std::pair<...>
он не работает! Чтобы получить код для компиляции, необходимо добавить конструктор копии delete
d (!) С movable const&
(или иметь только ту версию). Конструктор копирования, использующий ссылку не const
, является недостаточным:
#include <utility>
auto f() -> std::pair<int, movable> {
return std::pair<int, movable>(int(), movable());
}
Что здесь происходит? Является ли std::pair<...>
превышенным, указав, что std::pair(std::pair const&)
= default
ed?
Проблема, по-видимому, сводится к спецификации конструктора копирования std::pair
(в 20.3.2 [пар.пара]]:
namespace std { template <class T1, class T2> struct pair { ... pair(const pair&) = default; ... }; }
Быстрая проверка с моей реализацией подразумевает, что очевидная реализация, копирующая два элемента, не требует версии const&
конструктора копирования movable
. То есть, оскорбительная часть - это конструктор = default
в pair
!