Рассмотрим следующую пару взаимно ссылающихся типов:Инициализация взаимно ссылающихся объектов
struct A;
struct B { A& a; };
struct A { B& b; };
Это может быть инициализирована с совокупным инициализации в GCC, Clang, Intel, MSVC, но не SunPro, который настаивает на том, что определенные пользователем ctors необходимы.
struct {A first; B second;} pair = {pair.second, pair.first};
Является ли эта инициализация законной?
чуть более продуманные демо: http://ideone.com/P4XFw
Теперь, вняв предупреждение Солнца, что о классах с определенным пользователем конструкторами? Следующие работы в 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};
демо: http://ideone.com/QQEpA
И, наконец, что, если контейнер не является тривиальной либо, например, (Работает в G ++, Intel, Clang (с предупреждениями), но не MSVC ("пара" неизвестный в инициализаторе) или SunPro ("пара не структура")
std::pair<A, B> pair(pair.second, pair.first);
Из того, что я могу видеть, §3.8[basic.life]/6
, запрещает доступ к нестатическому элементу данных до начала жизни, но оценка lvalue для пары. второй «доступ» ко второй? Если это так, то все три инициализации незаконны? Также, §8.3.2[dcl.ref]/5
говорит: «Ссылка должна быть инициализирована для ссылки на действительный объект ", который, вероятно, также делает все три незаконных, но, возможно, мне что-то не хватает, и компиляторы принимают это по какой-то причине.
PS: Я понимаю, что эти классы практически не практичны, следовательно, la nguage-lawyer tag. Связанные и незначительно более практические старые обсуждения здесь: Circular reference in C++ without pointers
Я чувствую, что ваши совокупные конструкции верны (хотя я не могу это доказать сейчас), в то время как неагрегатная версия с 'std :: pair', конечно же, не допускается по причинам, которые вы заявляете. Вы можете задать более простой вопрос: 'struct Foo {Foo & r; Foo (Foo & f): r (f) {}} x (x);' –
Можете ли вы заставить его работать с указателями? –
Второй пример не является законным, насколько я могу судить, так как только агрегаты (которые могут не иметь конструкторы, объявленные пользователем) могут иметь инициализаторы-скобки: '§8.5 [dcl.init]/14' –