
Alexander Nasonov wrote:
Given that overall reaction is positive, I'll make the change, starting with the 'cast to reference' logic I wanted in the first place.
The only difference between my version and the one you mention above is this snippet in 'any_cast':
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro // to generate specialization of remove_reference for your class // See type traits library documentation for details BOOST_STATIC_ASSERT(!::boost::is_reference<nonref>::value); #endif
It looks to me that this assert will always be triggered when your
Vladimir Prus wrote: pass
reference type and BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION is defined, right? The assert will fire even if used has specialized remove_reference, no? If that's true, the comment is not correct and casting to reference is just not supported for broken compilers.
On broken compilers the assert for any_cast<int cv&> fires only if this thing is not in TU before first use of any_cast<int v&>:
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(int)
IMHO, if it's there, everything should work. BTW, there is a testcase in my earlier post in that thread. You can try to comment one such workaround to see the difference on a broken compiler or with BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION defined.
I think you're right, and trying gcc + BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION confirms that. I've committed this part of the patch.
I see that your patch also: 1. Strips cv-qualification in constructor (which is reasonable).
const is already stripped because ctor's argument is 'const ValueType & value'. So, it's only for volatile. remove_cv is used only to avoid inclusion of remove_volatile.hpp.
Does this use case matters, btw?
2. Strips cv-qualification when casting to pointer.
Why the second aspect is needed?
Quoting myself:
I forgot to mention that the original version has small problem with any_cast to const type. If any stores T and you cast it to T const you're trying this sequence of static_casts:
holder<T>* -> (in ctor) -> placeholder* -> (in any_cast) -> holder<T> const>*
Obviously, it's not getting back to original holder<T> type.
What about declaring that 'T' in all variants should have *no* cv-qualification? It's a bit strange that the user can cast to volatile type, and the any_cast will just throw that away. And cast *from* volalite any does not work, i.e. volatile boost::any a = 1; volatile int& i = boost::any_cast<volatile int&>(a); does not compile. So what's the point of allowing volatile type at all? - Volodya