C++ 中的嵌套子类
Nested subclasses in C++
我正在尝试创建一个嵌套的 class,它也是其父项的子项class:
struct X { struct Y : public X {}; };
不幸的是,这在 C++ 中似乎是不允许的,因为 g++ 会产生错误
error: invalid use of incomplete type 'struct X'
但是,我的实际代码有 X
作为模板 class:
template<typename T> struct X
{ struct Y : public X {}; };
我收到同样的消息,但这次只是警告:
warning: invalid use of incomplete type 'struct X< T >'
我的问题是:为什么前一种情况不合法,而模板化情况只是给出警告?模板化版本完全按照我的预期工作(我可以创建 X<T>::Y
的实例,将它们转换为 X<T>
,等等),但是警告是否意味着我不应该使用它?如果我忽略警告,我会 运行 遇到什么问题?
回答基本问题:您收到警告是因为模板尚未实例化,因此不会打扰任何人。
在这两种情况下,解决此问题的方法是在 X
的布局已知的位置定义 X::Y
,因此 Y
的布局可以适当推导。你可以这样做:
struct X { struct Y; }
struct X::Y {};
从技术上讲,就编译器而言,在实例化模板 (X
) 之前不需要知道基 (X
) 的布局。并且模板(X
)在完全定义之前可能不会被实例化。在这一点上,它的布局是已知的。
从模板中获取错误的最简单方法是尝试在 X
:
中实例化 Y
template<typename T> struct X {
struct Y : public X {};
Y y;
};
在早期版本的编译器中,您显示的情况下没有警告,但在某些时候添加了。这是来自 GCC bugtracker 的关于警告是否虚假的讨论。不确定标准是否允许这样做,但他们的结论是不允许。
因此,标准不允许使用这两种情况,但 GCC 会继续使用后者,因为它可以。
Yam Marcovic 展示了如何以符合标准的方式定义 X::Y
。 gcc bugtracker 中显示了类似的相同示例。
我正在尝试创建一个嵌套的 class,它也是其父项的子项class:
struct X { struct Y : public X {}; };
不幸的是,这在 C++ 中似乎是不允许的,因为 g++ 会产生错误
error: invalid use of incomplete type 'struct X'
但是,我的实际代码有 X
作为模板 class:
template<typename T> struct X
{ struct Y : public X {}; };
我收到同样的消息,但这次只是警告:
warning: invalid use of incomplete type 'struct X< T >'
我的问题是:为什么前一种情况不合法,而模板化情况只是给出警告?模板化版本完全按照我的预期工作(我可以创建 X<T>::Y
的实例,将它们转换为 X<T>
,等等),但是警告是否意味着我不应该使用它?如果我忽略警告,我会 运行 遇到什么问题?
回答基本问题:您收到警告是因为模板尚未实例化,因此不会打扰任何人。
在这两种情况下,解决此问题的方法是在 X
的布局已知的位置定义 X::Y
,因此 Y
的布局可以适当推导。你可以这样做:
struct X { struct Y; }
struct X::Y {};
从技术上讲,就编译器而言,在实例化模板 (X
) 之前不需要知道基 (X
) 的布局。并且模板(X
)在完全定义之前可能不会被实例化。在这一点上,它的布局是已知的。
从模板中获取错误的最简单方法是尝试在 X
:
Y
template<typename T> struct X {
struct Y : public X {};
Y y;
};
在早期版本的编译器中,您显示的情况下没有警告,但在某些时候添加了。这是来自 GCC bugtracker 的关于警告是否虚假的讨论。不确定标准是否允许这样做,但他们的结论是不允许。
因此,标准不允许使用这两种情况,但 GCC 会继续使用后者,因为它可以。
Yam Marcovic 展示了如何以符合标准的方式定义 X::Y
。 gcc bugtracker 中显示了类似的相同示例。