struct A;
struct B { A& a; };
struct A { B& b; };
在GCC、Clang、Intel和MSVC中,可以使用聚合初始化来进行初始化,但SunPro坚持要求必须使用用户定义的构造函数。
struct {A first; B second;} pair = {pair.second, pair.first};
这个初始化是否合法?
稍微详细的演示:http://ideone.com/P4XFw
现在,遵循Sun的警告,那么对于具有用户定义构造函数的类呢?下面的代码可以在GCC、clang、Intel、SunPro和MSVC中工作,但是它合法吗?
struct A;
struct B { A& ref; B(A& a) : ref(a) {} };
struct A { B& ref; A(B& b) : ref(b) {} };
struct {B first; A second;} pair = {pair.second, pair.first};
最后,如果容器也不是简单的情况呢,例如(在G ++,Intel,Clang(有警告)中工作,但在MSVC(“pair”未知于初始化程序)或SunPro(“pair不是一个结构”)中不起作用)
std::pair<A, B> pair(pair.second, pair.first);
据我所见,§3.8[basic.life]/6
禁止在对象生命周期开始之前访问非静态数据成员,但是对pair.second的lvalue求值是否算作对second的"访问"呢?如果是的话,那么这三个初始化是否都是非法的呢?另外,§8.3.2[dcl.ref]/5
说:“参考必须被初始化为指向有效对象”,这可能也使这三个初始化都非法了,但也许我漏看了什么,编译器出于某种原因接受这种情况。
PS:我意识到这些类在任何情况下都不实用,因此使用了“语言律师”标签。相关且稍微更实用的旧讨论在这里:Circular reference in C++ without pointers
std::pair
的非聚合版本则肯定不允许,原因就像你所说的那样。你可以问一个更简单的问题:struct Foo { Foo & r; Foo(Foo & f) : r(f) { } } x(x);
- Kerrek SB§8.5[dcl.init]/14
。 - Emil Styrkethis
:UB还是危险?(我相信,它几乎回答了你的问题,“这是不可能的”) - bitmask