4

考虑这个模板:

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视为等效项,考虑到 typedef,这似乎是合理的。然而dynamic_cast<>仅视为foo< int >::another_const_ref_t等同于const int&foo< int >::const_ref_t在另一种 ( ) 情况下,它将返回 null 。

为什么?

4

1 回答 1

6

考虑一下:

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

现在TRef与 相同Foo &,并且TCRef与 相同const Foo &

然而,const TRef是相同的const (TRef) = const (Foo &),不是(const Foo)&。但是引用类型总是不变的,所以额外的const并没有添加任何东西。

如果您更喜欢与指针进行比较:T&本质上是 like T * const,所以TRef constis like (T * const) const,它只是折叠为T * const.

于 2011-12-03T18:26:12.017 回答