This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of TS status.
any_cast doesn't work with rvalue reference targets and cannot move with a value targetSection: 6.4 [fund.ts.v2::any.nonmembers] Status: TS Submitter: Ville Voutilainen Opened: 2015-06-13 Last modified: 2017-07-30
Priority: 2
View all issues with TS status.
Discussion:
Addresses: fund.ts.v2
In Library Fundamentals v1, [any.nonmembers]/5 says:
For the first form,
*any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand). For the second and third forms,*any_cast<remove_reference_t<ValueType>>(&operand).
This means that
any_cast<Foo&&>(whatever_kind_of_any_lvalue_or_rvalue);
is always ill-formed. That's unfortunate, because forwarding such a cast
result of an any is actually useful, and such uses do not want to copy/move
the underlying value just yet.
Another problem is that that same specification prevents an implementation from moving to the target when
ValueType any_cast(any&& operand);
is used. The difference is observable, so an implementation can't perform
an optimization under the as-if rule. We are pessimizing every CopyConstructible
and MoveConstructible type because we are not using the move when
we can. This unfortunately includes types such as the library containers,
and we do not want such a pessimization!
[2015-07, Telecon]
Jonathan to provide wording
[2015-10, Kona Saturday afternoon]
Eric offered to help JW with wording
Move to Open
[2016-01-30, Ville comments and provides wording]
Drafting note: the first two changes add support for types that have explicitly deleted move constructors. Should we choose not to support such types at all, the third change is all we need. For the second change, there are still potential cases where Requires is fulfilled but Effects is ill-formed, if a suitably concocted type is thrown into the mix.
Proposed resolution:
This wording is relative to N4562.
In 6.3.1 [fund.ts.v2::any.cons] p11+p12, edit as follows:
template<class ValueType> any(ValueType&& value);-10- Let
-11- Requires:Tbe equal todecay_t<ValueType>.Tshall satisfy theCopyConstructiblerequirements, except for the requirements forMoveConstructible. Ifis_copy_constructible_v<T>isfalse, the program is ill-formed. -12- Effects: Ifis_constructible_v<T, ValueType&&>is true, cConstructs an object of typeanythat contains an object of typeTdirect-initialized withstd::forward<ValueType>(value). Otherwise, constructs an object of typeanythat contains an object of typeTdirect-initialized withvalue. […]
In 6.4 [fund.ts.v2::any.nonmembers] p5, edit as follows:
template<class ValueType> ValueType any_cast(const any& operand); template<class ValueType> ValueType any_cast(any& operand); template<class ValueType> ValueType any_cast(any&& operand);-4- Requires:
-5- Returns: For the first form,is_reference_v<ValueType>istrueoris_copy_constructible_v<ValueType>istrue. Otherwise the program is ill-formed.*any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand). For the secondand thirdforms,*any_cast<remove_reference_t<ValueType>>(&operand). For the third form, ifis_move_constructible_v<ValueType>istrueandis_lvalue_reference_v<ValueType>isfalse,std::move(*any_cast<remove_reference_t<ValueType>>(&operand)), otherwise,*any_cast<remove_reference_t<ValueType>>(&operand). […]