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

Why is a const templated reference type different from a const reference type?

本文关键字:引用类型 const 不同于 为什么      更新时间:2023-10-16

考虑这个模板:

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

我假设类型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.
}

对不起,这太复杂了,但这是我发现这个问题的情况的简化版本。

那么,问题是这样的。这段代码将const int&foo< int >::const_ref_tfoo< int >::another_const_ref_t视为等效的,在给定类型的情况下,这似乎是合理的。然而dynamic_cast<>只将foo< int >::another_const_ref_t等同于const int&。在另一种情况下(foo< int >::const_ref_t),它将返回null。

为什么?

考虑一下:

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

现在TRefFoo &相同,TCRefconst Foo &相同。

但是,const TRefconst (TRef) = const (Foo &)相同,而不是(const Foo)&。但是引用类型总是常量,所以额外的const不会增加任何东西。

如果你喜欢与指针进行比较:T&本质上像T * const,所以TRef const就像(T * const) const,它只是折叠成T * const

相关文章: