Рассмотрим следующую пару типов взаимной привязки:
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
Теперь, прислушиваясь к предупреждению 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};
demo: 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: Я понимаю, что эти классы никоим образом не практичны, поэтому тег-адвокат языка. Связанная и немного более практичная старая дискуссия здесь: Циркулярная ссылка в С++ без указателей