基子句之前的类声明是有效的前向声明吗?

问题描述 投票:0回答:1

我不确定我的问题标题是否最合适,如果我得到足够的建议,我会很乐意将其更改为更清晰的内容。

在一个主题不是这里的C++视频中,我看到了这个定义:

#include <vector>

// before ":" V is forward declared, it's enough for std::vector?
// node in a tree
struct V : std::vector<V> {};

(评论是我自己的)。

我的理解是,这种看似循环的声明是可能的,因为在

base-clause
位置,
struct V
已经(向前)声明了。

但是它是合法的C++吗,因为我没有发现类声明对此有明确的说明。

forward declaration
是由其自身定义的(
struct V;
,那么您可以声明
std::vector<V>)
,但不能在完整的类声明语法中声明。

派生类中的写法:

任何类类型(无论是使用类键类还是结构体声明)都可以声明为派生...

(粗体是我的) 似乎暗示

class-key class
class-key struct
(没有结尾
;
)已经是完整的声明。是真的吗,标准里更明确吗?

如果是的话,它可能会给我带来有趣设计的机会,所以我想确保它是合法的。

c++ inheritance language-lawyer forward-declaration
1个回答
0
投票

类名在标识符之后可以立即查找。请参阅 [basic.scope.pdecl]/3

但是,像往常一样,直到类定义结束

}
为止,类都是不完整的。基类说明符并不是一些所谓的“完整类上下文”的例外。 使用类型作为基类要求它是完整的。因此

std::vector<V>

将通过用作基类说明符来实例化,其中

V
仍然不完整。
通常使用不完整的类型作为模板参数实例化标准库模板会导致未定义的行为。

但是,由于 C++17

std::vector

是例外之一:允许使用不完整类型作为模板参数实例化

std::vector
,只要该类型在
std::vector
特化的任何成员函数之前完成即可参考。
所以是的,

struct V : std::vector<V> {};

自C++17起就有效,因为它在结束

std::vector<V>
之前不引用
}
的任何成员。
    

© www.soinside.com 2019 - 2024. All rights reserved.