I wanted to talk to you about how I handle std::any_cast<int &>(static_cast<any *>(nullptr)). The current fundamentals draft is not clear about how what happens when you call the non-throwing any_cast with a reference type. However there is a problem.
The signature of the non_throwing any_cast is as follows:
template<class ValueType>
const ValueType* any_cast(const any* operand) noexcept;
template<class ValueType>
ValueType* any_cast(any* operand) noexcept;
So when you instantiate any_cast<T&>(any*) you attempt to create the return type by adding a pointer to a reference. This causes the non-throwing any_cast to drop out of the overload resolution set. Now the overload resolution set only contains the throwing versions of any_cast. Since any has a non-explicit converting constructor C++ decides to construct a new any from the any pointer and then call the non-throwing any_cast. Then at run time when you make the call to any_cast it will throw an exception.
I think that the non-throwing any_cast should fail to compile when you ask it to cast a reference type. I think the best way to achieve this is to change the signatures of the non-throwing any_cast to the following and add internal static asserts that ValueType is not a reference.
template<class ValueType>
add_pointer_t<add_const_t<ValueType>> any_cast(const any* operand) noexcept;
template<class ValueType>
add_pointer_t<ValueType> any_cast(any* operand) noexcept;
We should also fix the draft as well. Let me know if you have any questions.