template<typename T>
struct base
{
struct usage : public base
{
};
};
这样的代码用 clang 编译没问题,用 gcc8.2 会产生一个 warning:
warning: invalid use of incomplete type 'struct base<T>'
标准是怎么说的呢?
1
shylockhg 2018-11-13 14:17:28 +08:00
继承的 base 需要特化
|
3
wutiantong OP @shylockhg 不是这样的,在这里加不加<T>是没有区别的,直接看在线代码吧: https://godbolt.org/z/uotlFp
|
4
shylockhg 2018-11-13 16:44:58 +08:00
@wutiantong 消除警告
|
5
shylockhg 2018-11-13 17:01:54 +08:00
|
6
wutiantong OP @shylockhg 你好像没有抓住重点。。。
我要讨论的情况下 enclosing class 是 template class 这将会允许我们在其中直接定义 inherit nested class 实际上,clang 和 gcc 都能编译通过这样的代码,但 gcc 会额外的产生 warning 更保守的写法(把 nested class 定义在后面)可以消除 warning 但我想知道的是原写法到底符不符合标准? |
7
shylockhg 2018-11-13 17:48:51 +08:00
@wutiantong 这就不清楚了,你要是搞清楚了可以分享下
|
8
FrankHB 2018-11-14 02:33:12 +08:00 1
按现在的说法:
http://eel.is/c++draft/temp.inst#1 没有明确类模板定义之后实例化之前的实例就是不完整类型,不过本来就是要求在完整类型的上下文中实例化,所以姑且没什么疑问。 http://eel.is/c++draft/temp.point#4 但是这里要求实例化的顺序就有问题了,嵌套的类总是在之前实例化,于是这里根本就没外面这个类的定义,而 base<T>这样的形式倒是被 http://eel.is/c++draft/temp.names#7 明确为类型名,所以是不完整类型。这是 G++报警告的原因。 实际上这是一个十几年来未解决的 CWG issue: https://wg21.cmeerw.net/cwg/issue287 按理想的解决方向就是 Clang++和 VC++这样的直接允许。 另见: https://stackoverflow.com/questions/37742749/point-of-instantiation-of-a-template-class 不过就这个例子,解决以后和非模板的情形还是不一样。非模板肯定还是不完整类型。和模板不同,因为根本没法在这里补充完整,还是会报错。 |
9
wutiantong OP @FrankHB 感谢大佬
|
10
FrankHB 2018-11-16 18:18:57 +08:00
今天又被坑了。。。G++7/8 没问题,Clang++7 不干了……
https://bitbucket.org/FrankHB/yslib/src/4ed6f283887b299b36896e9438674eab61008ffa/YBase/include/ystdex/range.hpp?fileviewer=file-view-default#range.hpp-297 还好刚对付过这个问题…… |