Здравствуйте, B0FEE664, Вы писали:
BFE>Почему некоторые компиляторы это отказываются компилировать ?
Реализация variant-ов кривая
Добавь туда пару типов std::variant<bool,FService> data_;
или пустой конструктор FService::FService() {}
и заработает
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, B0FEE664, Вы писали:
BFE>>Почему некоторые компиляторы это отказываются компилировать ?
M>Лучше соответствуют стандарту?
Если убрать инициализацию (int nFService_ = 0; ) то компилируется.
Такая инициализация перестала быть стандартной?
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Великий Мессия, Вы писали:
ВМ>>в так в GCC тоже самое ВМ>>сомневаюсь что два мажорный компиля синхронно не правы
R>Ну, в таком случае очень хотелось бы найти объяснение.
R>Выглядит очень странно: вынос структуры наружу или отказ от инициализации мембера устраняют ошибку. Кто-нибудь видит связь или логику? Я — нет.
согласен
если бы не засветили здесь эту проблему
я бы сходил в issue кланга или на багзиллу gcc
задал вопросик
по issues кланга я похожих кейсов не нашел
так что, велком кто то зарепортите
и оставьте линк сюда
для мониторинга
Здравствуйте, rg45, Вы писали:
R>Ну, в таком случае очень хотелось бы найти объяснение.
R>Выглядит очень странно: вынос структуры наружу или отказ от инициализации мембера устраняют ошибку. Кто-нибудь видит связь или логику? Я — нет.
типа в этом случае вложенный класс считается неполным до завершения объявления внешнего
This declares a default constructor that might be defined implicitly by the compiler, **or** it might get deleted if the member definitions of D would make the implicit default constructor ill-formed. This is obviously very different from the case where you declare B(); There is no assertion that D is default constructible, the compiler has to deduce whether or not that's true. That depends on the default member initializer for D::i. The initializer (which is just '0' here) is a "complete class context" which means it is not processed until the class D is complete (this allows you to use other members, or e.g. sizeof(D) as the initializer).
A nested class like C::D is not complete until its enclosing class is complete. This means the initializer for C::D::i is compiled after C is complete. This means whether C::D is default constructible is not known until C is complete.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, sergii.p, Вы писали:
R>Имхо, самое важное в этом беспорядочном потоке сознания заключено вот в этом коротеньком утверждении:
R>
R>A nested class like C::D is not complete until its enclosing class is complete.
R>Вот если бы ещё получить ссылку на соответствующий пункт стандарта, было бы совсем здорово.
R>struct D
R>{
R> struct FService
R> {
R> int nFService_ = 0;
R> };
R> static_assert(sizeof(FService) != 0); // OK
// не является complete-class context так как не является ни одним из перечисленных вариантов в 10.1 - 10.6 отсюда https://timsong-cpp.github.io/cppwp/class.mem.general#10
R> static_assert(std::default_initializable<FService>); // static assertion failed
// тут complete-class context это инициализирующее выражение "0" для FService::nFService_ (https://timsong-cpp.github.io/cppwp/class.mem.general#10.6), размещенное "within the member-specification", коим является static_assert (https://timsong-cpp.github.io/cppwp/class.mem.general#nt:member-declaration)
// этот complete-class context провоцирует дефолтный конструктор FService к удалению, тест default_initializable проваливается, получаем ложь и провал static_assert
R>};
R>
R>Выходит, класс "достаточно полный" для sizeof, но недостаточно полный для того, чтобы понять, что он default infitializable. Это как так?
R>>struct D
R>>{
R>> struct FService
R>> {
R>> int nFService_ = 0;
R>> };
R>> static_assert(sizeof(FService) != 0); // OK
V>// не является complete-class context так как не является ни одним из перечисленных вариантов в 10.1 - 10.6 отсюда https://timsong-cpp.github.io/cppwp/class.mem.general#10
R>> static_assert(std::default_initializable<FService>); // static assertion failed
V>// тут complete-class context это инициализирующее выражение "0" для FService::nFService_ (https://timsong-cpp.github.io/cppwp/class.mem.general#10.6), размещенное "within the member-specification", коим является static_assert (https://timsong-cpp.github.io/cppwp/class.mem.general#nt:member-declaration)
V>// этот complete-class context провоцирует дефолтный конструктор FService к удалению, тест default_initializable проваливается, получаем ложь и провал static_assert
R>>};
R>>
Примерно понял, спасибо. Почитаю ещё документ повнимательнее.
PS. Хотя логика этих зависимостей мне не очень понятна. Получается, что в обрамляющем классе можно написать нечто такое, отчего вложенный класс не сможет быть default initializable. В противном случае зачем эти сложности.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Вот если бы ещё получить ссылку на соответствующий пункт стандарта, было бы совсем здорово.
[class.mem.general]
[Note 4 : A complete-class context of a nested class is also a complete-class context of any enclosing class, if the nested
class is defined within the member-specification of the enclosing class. — end note]
7 A class is considered a completely-defined object type (6.8) (or complete type) at the closing } of the
class-specifier. The class is regarded as complete within its complete-class contexts; otherwise it is regarded
as incomplete within its own class member-specification.
Здравствуйте, sergii.p, Вы писали:
SP>Здравствуйте, rg45, Вы писали:
R>>Вот если бы ещё получить ссылку на соответствующий пункт стандарта, было бы совсем здорово.
SP>[class.mem.general]
SP>
SP>[Note 4 : A complete-class context of a nested class is also a complete-class context of any enclosing class, if the nested
SP>class is defined within the member-specification of the enclosing class. — end note]
SP>7 A class is considered a completely-defined object type (6.8) (or complete type) at the closing } of the
SP>class-specifier. The class is regarded as complete within its complete-class contexts; otherwise it is regarded
SP>as incomplete within its own class member-specification.
о! нашел таки на llvm
работают над исправлением как я понял,но вяло
ну так и в этом тикете такая же лапша. "Классы, контексты какие-то. Взять всё, и починить!". А меж тем тикету 3 года уже. Думаю разработчики сами плохо понимают аргументацию в стандарте, но это хорошая отмазка не чинить