Why is the template type with a constant template different from the reference type const?

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 ); // Fails assert( b ); // Succeeds } }; void fn() { abstractBase* p = new otherClass< const int& >(); foo< int > f; f.discover( p ); // Assertion on 'a' fails. } 

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?

+4
source share
1 answer

Consider this:

 typedef Foo T; typedef T & TRef; typedef T const & TCRef; 

Now TRef matches Foo & , and TCRef matches const Foo & .

However, const TRef same as const (TRef) = const (Foo &) , not (const Foo)& . But reference types are always constant, so the extra const adds nothing.

If you prefer comparisons with pointers: T& is essentially similar to T * const , so TRef const is similar to (T * const) const , which simply collapses to T * const .

+6
source

Source: https://habr.com/ru/post/1384492/


All Articles