3

BREAK が定義されている場合、g++ 4.7.2 は以下をコンパイルしません。これは有効な C++ だと思います。A<U> tmpが何か他のものに変更された場合、定義された BREAK でコンパイルされますA<int> tmp。これにより、ここでの最小限のテストケースが機能しますが、実際のアプリケーションではうまくいきません。合法的な C++ ではないものはありますか?

template <typename T>
class B {

};

template <typename T>
class A {
public:
    template <typename U> B<U> *alloc_B( );
};

template <typename T> template <typename U>
B<U> *A<T>::alloc_B( ) {
    return new B<U>( );
}

#ifdef BREAK
template <typename T>
class C {
public:
    template <typename U> void x(B<U> &b) {
        A<U> tmp;
        B<U> *tmp2;
        tmp2 = tmp.alloc_B<U>( );
        delete tmp2;
    }
};
#endif

int main( ) {
    A<int> a;
    B<float> *bp = a.alloc_B<float>( );
    delete bp;

#ifdef BREAK
    C<int> c;
    B<float> b;

    c.x(b);
#endif
}
4

2 に答える 2

6

alloc_B関数テンプレートは従属名です。次のように呼び出す必要があります。

tmp2 = tmp.template alloc_B<U>( );

それが問題でありA<int>、型がテンプレート引数に依存しなくなったため、を使用すると機能するのはそのためUです。

于 2013-04-05T01:16:06.530 に答える
5

これは、C++の煩わしい解析規則の 1 つによるものです。を見るとtmp.alloc_B<U>、これはテンプレートとしてではなく、 として解釈されtmp.alloc_B < Uます。これを修正するには、これがテンプレートであることを明示的に指定する必要があります。

tmp2 = tmp.template alloc_B<U>( );
于 2013-04-05T01:18:32.723 に答える