为什么const模板化引用类型与const引用类型不同?

Old*_*ier 4 c++ templates dynamic-cast typedef

考虑这个模板:

template< typename T, typename RefT = T& >
class foo
{
    typedef const RefT const_ref_t;
    typedef const T&   another_const_ref_t;

    //...

};
Run Code Online (Sandbox Code Playgroud)

我会假设类型const_ref_tanother_const_ref_t等价物.两者都是const T&.但事实并非如此.唉,以下关于它们不等价的证明是相当复杂的.它取决于使用dynamic_cast<>来检查另一个类的类型.

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.
}
Run Code Online (Sandbox Code Playgroud)

对不起,这是如此复杂,但它是我发现问题的情况的简化版本.

那么问题是这个.此代码对待const int&,foo< int >::const_ref_tfoo< int >::another_const_ref_t等同,这似乎是合理的给出的类型定义.然而,dynamic_cast<>只把对待foo< int >::another_const_ref_t等同于const int&.它将在other(foo< int >::const_ref_t)情况下返回null .

为什么?

Ker*_* SB 6

考虑一下:

typedef Foo T;
typedef T & TRef;
typedef T const & TCRef;
Run Code Online (Sandbox Code Playgroud)

现在TRef是一样的Foo &,和TCRef是一样的const Foo &.

但是,const TRefconst (TRef) = const (Foo &)不一样的(const Foo)&.但是引用类型总是不变的,因此附加类型const不会添加任何内容.

如果你喜欢用三分球进行比较:T&基本上是一样T * const,所以TRef const就像是(T * const) const,刚刚瓦解成T * const.