Consider this template:
template< typename T, typename RefT = T& > class foo { typedef const RefT const_ref_t; typedef const T& another_const_ref_t;
I would suggest that the types const_ref_t
and another_const_ref_t
would be equivalent. Both parameters are const T&
. But this is not so. Alas, the following demonstration of their nonequivalence is quite complicated. It depends on using dynamic_cast<>
to check the type of another class.
class abstractBase { public: virtual ~abstractBase() {} }; template< typename T > class otherClass : public abstractBase { }; template< typename T, typename RefT = T& > class foo { typedef const RefT const_ref_t; typedef const T& another_const_ref_t; public: void discover( abstractBase* p ) { otherClass< const_ref_t >* a = dynamic_cast< otherClass< const_ref_t >* >( p ); otherClass< another_const_ref_t >* b = dynamic_cast< otherClass< another_const_ref_t >* >( p ); assert( a );
Sorry, this is so complicated, but this is a simplified version of the situation when I discovered this question.
So the question is. This code considers const int&
, foo< int >::const_ref_t
and foo< int >::another_const_ref_t
as equivalent, which seems reasonable given typedefs. However, dynamic_cast<>
treats foo< int >::another_const_ref_t
as the equivalent of const int&
. It returns null in another ( foo< int >::const_ref_t
) case.
Why?
source share