списке инициализации, верно?
Только для инициализации других мемберов или хак с оператором запятая, но тоже при иниациализации
struct Foo { int init() { return 5;} int i; Foo() : i(init()) {} };
То есть, если метод класса меняет внутри себя поле этого же класса, то этот метод нельзя вызвать в списке инициализации конструктора этого класса?
Для вызова методов есть тело конструктора, зачем обязательно что-то сложное делать в списке инициализации?
Как так получается, объект же не до конца сконструирован => почему метод init() работает?
так делать плохо. но не запрещено
Вызов методов в теле конструктора, ведь, не удивителен?
Так делать вполне нормально, пока метод не виртуальный
ну я стараюсь так не делать. были как-то баги при активном использовании функций мемберов в конструкторе. в идеале дефолтный конструктор должен быть пустым. благо С++ современный это позволяет
да и с виртуальным проблем не должно быть. vptr то в конструкторе инициализирован. просто не конечным значением иницализирован. но те, кто зовут виртуальные функции из конструкторов, понимают, что делают
и правда... меня, скорее, смутило то, что метод вызывался до фигурных скобок. У меня ошибочное представление о работе конструктора. Спасибо
Помним про чистые виртуальные :)
Можно любую функцию, надо только использовать еë значение для инициализации
Можно пример?
Тебе дали уже пример
А если поле не инициализировано?
То будет UB
А для чего так кровь из носа нужно метод в списке инициализации именно вызывать?
Причем здесь кровь из носа? Мне надо просто знать, можно так или нет.
И без этого нормально же жилось)
Можно как угодно, но надо помнить, что уже сконструировано, а что еще нет
Можно было и плюсы не учить тогда. В с Си нормально жилось же )
Ну тоже справедливо, но RAII не завезли
Вот пример. В нем i инициализировано, но не компилится нихрена.
А в блоке инициализации почему нельзя вызвать? Уже писали, что именно так нельзя
Я читал все, что писали. Но @MasterZiv говорит, что можно.
Можно в выражении с инициализацией нестатичного поле
Можно, но надо думать, что будет.
Там выше код посмотри
Жесть какая-то. Вы объясните, почему код не компилится то?
в списке инициализации могут фигурировать только data members или конструкторы но в инициализаторах, которые в фигурных или круглых скобках, можно писать любые выражения. но нужно держать в уме состояние объекта, это да
Наконец-то нормальное объяснение. Благодарю!
Список инициализации предназначен для инициализации полей, не для вызова методов, если очень хочется инициализировать поле вызовом метода, то или перемести вызов метода в тело конструктора, либо делай i(init(5))
Потому что башкой не думаешь, у тебя метод void!
Чего? Любое возможное выражение там может быть
Ну в круглых скобках же только
какая разница какой у меня метод? Вопрос был просто можно вызывать методы в списке инициализации или нет. Я не спрашивал можно ли инициализировать возвращаемым значением метода поля класса.
Даже такое? Foo() : myMemberFunc() {} ?
Да какая разница то?
Вернулись к моему изначальному примеру, лол...
Такое нельзя
Как же так? Вы же говорили любое можно!
В инициализаторе поля может использоваться любое выражение, валидное для инициализации поля этого типа, в том числе и вызов метода класса/структуры. Но вызов нестатичных мемберов в инициализаторе может привести к UB, за этим нужно следить
Вообще не знаю где это пригодится может
что инициализировано, а что нет к моменту вычисления того или иного выражения в member initializer list можно почитать здесь: http://eel.is/c++draft/class.init#class.base.init-13.3
здравствуйте http://eel.is/c++draft/class.init#class.base.init-2.sentence-4
Яж говорил мозг включать...
Это описывает имя в списке инициализации. А чем его инициализировать - это любое выражение, дающее значение того типа, чей член мы инициализируем, или проводимого типа
я же это и написал
Так это не означает что там нельзя вызвать функцию
>но в инициализаторах, которые в фигурных или круглых скобках, можно писать любые выражения где тут какие ограничения на вызов функций?
Вы можете накидать в лямбду любой код, и не сообщить компилятору через клобберы, что именно вы туда накидали. Жестокая реальность такова, что при должной комбинации запретов и умалчивания компилятору ничего не останется, как бессильно плакать, глядя на вашу жестокость без права вмешаться
Не очень понял, что я только что прочитал. Вы можете показать пример?
[](){asm volatile(".word 0xDEADBEEF");}
Хороший код. Не вижу повода для слёз
Плохой, если энкодинг соответствует, например, джампу, а мы не сказали, что это он
Обсуждают сегодня