考虑这个模板:
template< typename T, typename RefT = T& >
class foo
{
typedef const RefT const_ref_t;
typedef const T& another_const_ref_t;
//...
};
我会假设类型const_ref_t和another_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_t和foo< int >::another_const_ref_t视为等效项,考虑到 typedef,这似乎是合理的。然而dynamic_cast<>仅视为foo< int >::another_const_ref_t等同于const int&。foo< int >::const_ref_t在另一种 ( ) 情况下,它将返回 null 。
为什么?