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&'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_tconst int&foo< int >::const_ref_t

なんで?

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&は本質的にはのようでありT * const、のようになり、はに折りたたまれます。TRef const(T * const) constT * const

于 2011-12-03T18:26:12.017 に答える