g++不能编译某些嵌套模板

3

当定义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
}
2个回答

6

alloc_B函数模板是一个相关名称。您必须按如下方式调用它:

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

那就是问题所在,这也是为什么使用 A<int> 时能够正常运行的原因,因为类型不再依赖于模板参数 U

5

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接