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_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.
}
Run Code Online (Sandbox Code Playgroud)
对不起,这是如此复杂,但它是我发现问题的情况的简化版本.
那么问题是这个.此代码对待const int&,foo< int >::const_ref_t和foo< int >::another_const_ref_t等同,这似乎是合理的给出的类型定义.然而,dynamic_cast<>只把对待foo< int >::another_const_ref_t等同于const int&.它将在other(foo< int >::const_ref_t)情况下返回null .
为什么?
考虑一下:
typedef Foo T;
typedef T & TRef;
typedef T const & TCRef;
Run Code Online (Sandbox Code Playgroud)
现在TRef是一样的Foo &,和TCRef是一样的const Foo &.
但是,const TRef是const (TRef) = const (Foo &)不一样的(const Foo)&.但是引用类型总是不变的,因此附加类型const不会添加任何内容.
如果你喜欢用三分球进行比较:T&基本上是一样T * const,所以TRef const就像是(T * const) const,刚刚瓦解成T * const.