Почему С++ 17 std:: any не позволяет возвращать подвижное значение any_cast?

При реализации С++ 17 std::any в соответствии с имеющейся спецификацией в этой вики я наткнулся на то, что казалось мне бессмысленным:

В определении свободной функции std::any_cast, которая используется для извлечения значений из экземпляра std::any, перегрузка для r-value (это третий):

template< class ValueType >
ValueType any_cast(any&& operand); // (3)

Теперь есть перечисленное ниже требование, которое относится к перегрузкам 2 и 3 (это означает также включение перегрузки r-значения):

2-3) Возвращает *any_cast<std::remove_reference_t<ValueType>>(&operand)

Определение , по-видимому, не позволяет перемещать данные!

Вызов функции просто перенаправлен на перегрузку на основе указателя; информация о временном характере operand теряется!

Предполагается ли, что я не могу уйти из какого-либо экземпляра? Это просто ошибка в wiki? Я здесь не прав?

Ответы

Ответ 1

Проблема заключается в статусе WP во время написания этого сообщения, что означает:

WP - (Рабочий документ). Предлагаемая резолюция не была принята в качестве технического исправления, но полный комитет WG21/PL22.16 проголосовал за применение предлагаемой резолюции о дефекте в рабочем документе.

Смотрите здесь lwg для получения дополнительной информации: http://wg21.cmeerw.net/lwg/issue2509

Предлагаемая резолюция действительно

Для третьей формы, если is_move_constructible_v<ValueType> истинно, а is_lvalue_reference_v<ValueType> - false, std::move(*any_cast<remove_reference_t<ValueType>>(&operand)), в противном случае *any_cast<remove_reference_t<ValueType>>(&operand)

И список отчетов о дефектах, перечисляющий WP: http://cplusplus.github.io/LWG/lwg-defects.html#2509

Ответ 2

Реализация std::any, которая не требует копирования, вполне возможна. Там только одна проблема: что вы делаете, когда пользователь запрашивает копию std::any? Одно из решений этой проблемы состоит в том, чтобы сделать std::any только перемещение, а другое - заставить исключить конструктор копирования, если базовый тип - только для перемещения, а другой должен иметь возможность копировать базовый тип. Было выбрано третье решение.

Требования к ValueType, являющиеся копируемыми конструкциями, совершенно прекрасны - поскольку тип, который не копирует конструкцию, не может быть сохранен в экземпляре std::any, std::any_cast может также сделать всегда неудачный листинг a ошибка компилятора.

Теперь тот факт, что реализация ValueType any_cast(any&& operand) не позволяет перемещаться, кажется, является надзором - в конце концов, копия - прекрасная реализация перемещения, и реализация может свободно делегировать задание на ходу конструктор, если он есть, и скопировать конструктор, если нет.