我很惊讶地发现,以下代码无法使用CGG 5或更低版本进行编译,尽管它在clang 4或CGG 6(及更高版本)下可以正常工作。
我真的看不到出什么问题了,它遮盖了B
类的模板参数。更重要的是,我看不到应该如何对其进行调整,以使其能够与旧版GCC一起编译...
#include <array>
template <typename T, int N>
struct A {
public:
std::array<T, 3> coordinates = { };
};
template <typename T, int N>
class B {
public:
A<T, N> *myA = new A<T, N>();
};
编译器输出:
<source>:12:29: error: expected ';' at end of member declaration
A<T, N> *myA = new A<T, N>();
^
<source>:12:29: error: declaration of 'A<T, N> B<T, N>::N'
<source>:9:23: error: shadows template parm 'int N'
template <typename T, int N>
^
<source>:12:30: error: expected unqualified-id before '>' token
A<T, N> *myA = new A<T, N>();
^
<source>:12:26: error: wrong number of template arguments (1, should be 2)
A<T, N> *myA = new A<T, N>();
^
<source>:4:8: error: provided for 'template<class T, int N> struct A'
struct A {
^
Compiler exited with result code 1
最佳答案
这is a GCC5 bug。您可以通过多种方式解决它。如in the comments所指出的,最简单的方法可能是在新表达式周围添加括号:
template <typename T, int N>
class B {
public:
A<T, N> *myA = (new A<T, N> ());
};
另一种方式,如果您经常使用该类型,则可能是一个好主意,那就是将
using a_type = A<T, N>;
添加到类中,然后说new a_type
:template <typename T, int N>
class B {
private:
using a_type = A<T, N>;
public:
A<T, N> *myA = new a_type();
};
尽管似乎没有必要,但我添加了
main
函数来确保模板实例化,以防万一影响到该错误:int main() {
B<int, 5> b1, b2;
b1.myA->coordinates = {{1, 2, 3}};
return b2.myA->coordinates.size();
}
另外,我假设这些只是做一个最小示例的 Artifact ,但以防万一,还有几点要点:
class B
发生内存泄漏:它永远不会delete
指向它的指针new
。 class B
中的指针是不必要的间接级别,A
(或仅std::array
)应为直接成员。