G++ 不编译某些嵌套模板

g++ doesn't compile certain nested templates

本文关键字:嵌套 编译 G++      更新时间:2023-10-16

当定义BREAK时,g++ 4.7.2将不会编译以下内容,我认为这是有效的c++。如果将A<U> tmp更改为其他东西(如A<int> tmp),则会使用定义的BREAK进行编译-虽然这使得这里的最小测试用例工作,但在我的实际应用程序中并不好。这里有什么不合法的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
}

alloc_B函数模板为依赖模板名。你必须这样称呼它:

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

这就是问题所在,这就是为什么当您使用A<int>时它可以工作的原因,因为类型不再依赖于模板参数U

这是由于C++的一个令人讨厌的解析规则。当它看到tmp.alloc_B<U>时,不会将其解释为模板,而是解释为tmp.alloc_B < U。要解决这个问题,您需要显式指定这是一个模板:

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