このテンプレートを検討してください。
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&
'sです。しかし、そうではありません。残念ながら、次の非等価性のデモンストレーションはかなり複雑です。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<>
扱われるだけです。他の( )の場合はnullを返します。foo< int >::another_const_ref_t
const int&
foo< int >::const_ref_t
なんで?