Title
Redundant const in the return type of any_cast(const any&)
Status
c++17
Section
[any.nonmembers]
Submitter
Casey Carter

Created on 2016-09-02.00:00:00 last changed 90 months ago

Messages

Date: 2016-12-16.21:09:36

Proposed resolution:

This wording is relative to N4606.

  1. Modify [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: 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.

    -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).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))).

    […]

Date: 2017-02-02.00:41:18

[ Issues Telecon 16-Dec-2016 ]

Move to Tentatively Ready

Date: 2016-11-15.00:00:00

[ 2016-11-10, LWG asks for simplification of the wording ]

Date: 2016-10-15.00:00:00

[ 2016-10-16, Eric made some corrections to the wording ]

Previous resolution [SUPERSEDED]:

This wording is relative to N4606.

  1. Modify [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.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.

    -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).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))).

    […]

Date: 2016-09-15.00:00:00

[ 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.

Date: 2016-09-09.00:00:00

[ 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.

  1. Modify [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 and second and third forms, *any_cast<remove_reference_t<ValueType>>(&operand). For the third form, std::forward<ValueType>(*any_cast<remove_reference_t<ValueType>>(&operand)).

    […]

Date: 2016-09-09.00:00:00

[ 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.

  1. Modify [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).

    […]

Date: 2016-09-02.00:00:00

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.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2017-03-05 23:41:16adminsetstatus: ready -> wp
2016-12-16 21:09:36adminsetmessages: + msg8755
2016-12-16 21:09:36adminsetstatus: open -> ready
2016-11-10 19:10:18adminsetmessages: + msg8618
2016-10-16 11:50:44adminsetmessages: + msg8569
2016-10-05 19:39:12adminsetmessages: + msg8536
2016-10-05 19:39:12adminsetstatus: ready -> open
2016-09-27 18:52:57adminsetmessages: + msg8522
2016-09-12 04:36:33adminsetmessages: + msg8510
2016-09-12 04:36:33adminsetstatus: new -> ready
2016-09-05 18:44:40adminsetmessages: + msg8495
2016-09-02 00:00:00admincreate