Mas*_*ano 26 c++ language-lawyer
浏览标准草案(n3242)我在第9.2条(强调我的)中找到了这句话:
非静态(9.4)数据成员不应具有不完整类型.特别是,类C不应包含类C的非静态成员,但它可以包含指向C类对象的指针或引用.
从这里我认为可以定义这样的类:
class A {
public:
A(A& a) : a_(a){
}
private:
A& a_;
};
Run Code Online (Sandbox Code Playgroud)
然后在第8.3.2节中我发现了以下内容:
应初始化引用以引用有效的对象或函数
问题1:是否允许定义此类型的对象,并将其名称作为参考:
A a(a);
Run Code Online (Sandbox Code Playgroud)
或者这会触发未定义的行为?
问题2:如果是,标准的哪些部分允许从仍待构建的对象初始化引用?
问题3:如果不是,这是否意味着A类的定义形式良好但是没有触发UB就不能创建第一个对象?在这种情况下,这背后的理由是什么?
n3337 § 3.8/6
类似地,在对象的生命周期开始之前但在对象将占用的存储已经被分配之后,或者在对象的生命周期结束之后并且在对象占用的存储被重用或释放之前,任何引用的glvalue之前可以使用原始对象,但仅限于有限的方式.对于正在建造或销毁的物体,见12.7.否则,这样的glvalue指的是已分配的存储(3.7.4.2),并且使用不依赖于其值的glvalue的属性是明确定义的.如果出现以下情况,该程
- 对这样的glvalue应用左值到右值的转换(4.1),
- glvalue用于访问非静态数据成员或调用对象的非静态成员函数,或
- glvalue被隐式转换(4.10)到对基类类型的引用,或
- glvalue用作static_cast(5.2.9)的操作数,除非转换最终是cv char&或cv unsigned char&,或者
- glvalue用作dynamic_cast(5.2.7)的操作数或typeid的操作数.
那么,回答你的问题:
问题1:是否允许定义此类型的对象将其名称作为参考?
是.使用只是地址似乎不违反这个(至少对于放在堆栈上的变量).
A a(a);
或者这会触发未定义的行为?
没有.
问题2:如果是,标准的哪些部分允许从仍待构建的对象初始化引用?
§3.8/6(上)
剩下的唯一问题是这是如何对应的
应初始化引用以引用有效的对象或函数.
问题在于术语有效对象.因为§ 8.3.2/4说,
未指定引用是否需要存储
似乎§ 8.3.2是有问题的,应改写.的混乱导致改变建议在文件C++标准核心语言活跃问题,修订87日在二○一四年一月二十〇日:
应初始化引用以引用对象或函数.
更改8.3.2 [dcl.ref]第4段如下:
如果引用直接绑定到的左值既不指定现有对象或适当类型的函数(8.5.3 [dcl.init.ref]),也不指定合适大小和对齐的内存区域以包含对象引用的类型(1.8 [intro.object],3.8 [basic.life],3.9 [basic.types]),行为未定义.