This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.
Section: 22.7.5 [any.nonmembers] Status: C++17 Submitter: Casey Carter Opened: 2016-09-02 Last modified: 2017-07-30
Priority: 0
View other active issues in [any.nonmembers].
View all other issues in [any.nonmembers].
View all issues with C++17 status.
Discussion:
The overload of any_cast that accepts a reference to constant any:
template<class ValueType> ValueType any_cast(const any& operand);
is specified to return *any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand) in [any.nonmembers]/5. This calls the pointer-to-constant overload of any_cast:
template<class ValueType> const ValueType* any_cast(const any* operand) noexcept;
which is specified as:
Returns: If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object contained by operand; otherwise, nullptr.
Since typeid(T) == typeid(const T) for all types T, any_cast<add_const_t<T>>(&operand) is equivalent to any_cast<T>(&operand) for all types T when operand is a constant lvalue any. The add_const_t in the return specification of the first overload above is therefore redundant.
[2016-09-09 Issues Resolution Telecon]
P0; move to Tentatively Ready
Casey will provide combined wording for this and 2768, since they modify the same paragraph.
Previous resolution [SUPERSEDED]:
This wording is relative to N4606.
Modify 22.7.5 [any.nonmembers] as indicated:
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: is_reference_v<ValueType> is true or is_copy_constructible_v<ValueType> is true. Otherwise the program is ill-formed.
-5- Returns: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). […]
[2016-09-09 Casey improves wording as determined by telecon]
The presented resolution is intended as the common wording for both LWG 2768 and LWG 2769.
Previous resolution [SUPERSEDED]:
This wording is relative to N4606.
Modify 22.7.5 [any.nonmembers] as indicated:
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: is_reference_v<ValueType> is true or is_copy_constructible_v<ValueType> is true. Otherwise the program is ill-formed.
-5- Returns: For the firstform, *any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand). For theand secondand thirdforms, *any_cast<remove_reference_t<ValueType>>(&operand). For the third form, std::forward<ValueType>(*any_cast<remove_reference_t<ValueType>>(&operand)). […]
[2016-10-05, Tomasz and Casey reopen and improve the wording]
The constraints placed on the non-pointer any_cast overloads are neither necessary nor sufficient to guarantee that the specified effects are well-formed. The current PR for LWG 2769 also makes it possible to retrieve a dangling lvalue reference to a temporary any with e.g. any_cast<int&>(any{42}), which should be forbidden.
[2016-10-16, Eric made some corrections to the wording]
Previous resolution [SUPERSEDED]:
This wording is relative to N4606.
Modify 22.7.5 [any.nonmembers] as indicated:
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:is_reference_v<ValueType> is true or is_copy_constructible_v<ValueType> is true.For the first overload, is_constructible_v<ValueType, const remove_cv_t<remove_reference_t<ValueType>>&> is true. For the second overload, is_constructible_v<ValueType, remove_cv_t<remove_reference_t<ValueType>>&> is true. For the third overload, is_constructible_v<ValueType, remove_cv_t<remove_reference_t<ValueType>>> is true. Otherwise the program is ill-formed.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).For the first and second overload, static_cast<ValueType>(*any_cast<remove_cv_t<remove_reference_t<ValueType>>>(&operand)). For the third overload, static_cast<ValueType>(std::move(*any_cast<remove_cv_t<remove_reference_t<ValueType>>>(&operand))). […]
[2016-11-10, LWG asks for simplification of the wording]
[Issues Telecon 16-Dec-2016]
Move to Tentatively Ready
Proposed resolution:
This wording is relative to N4606.
Modify 22.7.5 [any.nonmembers] as indicated:
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);-?- Let U be the type remove_cv_t<remove_reference_t<ValueType>>.
-4- Requires:
-5- Returns:is_reference_v<ValueType> is true or is_copy_constructible_v<ValueType> is true.For the first overload, is_constructible_v<ValueType, const U&> is true. For the second overload, is_constructible_v<ValueType, U&> is true. For the third overload, is_constructible_v<ValueType, U> is true. Otherwise the program is ill-formed.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).For the first and second overload, static_cast<ValueType>(*any_cast<U>(&operand)). For the third overload, static_cast<ValueType>(std::move(*any_cast<U>(&operand))). […]