Все откомпилировалось и работает без проблем. Предупреждений 4-го уровня тоже нет.
Где-то в глубине души меня беспокоит такая конструкция func1(&func2()). Но она компилируется и работает. То есть, временный объект, возвращаемый из func2, живет до конца вызова func1.
Как сделать лучше — не знаю.
Собственно вопрос — это нормальный подход или могут возникнуть проблем?
Еще раз отмечу, что add_current_errors указатель/ссылку на t_errors внутри не запоминает.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: Передача объекта, возвращаемого функцией, в другую функцию.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>У него две реализации — t_errors_without_limits и t_errors_with_limits
КД>Есть два метода, возвращающие экземпляры этих реализацией: КД>
КД>Все компилируется (VC++) и работает как и ожидается.
КД>При включенном 4-ом уровне предупреждений, компилятор предупреждает, что нельзя передавать по ссылке результат метода.
errs внутри add_current_errors изменяется? если нет, поставь const.
какой другой компилятор тебя и за взятие адреса rvalue отругает, так что не решение.
Re: Передача объекта, возвращаемого функцией, в другую функц
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Теперь есть утилита, работающая с t_errors: КД>
КД>void add_current_errors(t_errors& errs); //errs внутри не запоминается.
КД>
Тут должен быть const :
void add_current_errors(const t_errors& errs);
КД>Собственно вопрос — это нормальный подход или могут возникнуть проблем?
Подход не нормальный в том смысле, что не соответствует современным нормам.
Проблемы возникнуть могут, но они связаны не с работоспособностью кода (код рабочий), а с вопросами возникающими у читателя этого кода:
— если вы меняете errs внутри add_current_errors, то зачем вы это делаете?
— если вы не меняете errs внутри add_current_errors, то зачем он не const?
PS моя телепатия мне подсказывает, что у интерфейса t_errors есть виртуальные get-методы не обявленные const.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Как сделать лучше — не знаю.
КД>Собственно вопрос — это нормальный подход или могут возникнуть проблем?
КД>Еще раз отмечу, что add_current_errors указатель/ссылку на t_errors внутри не запоминает.
Здравствуйте, andrey.desman, Вы писали:
КД>>Нет, const тут не нужен, потому что в errs добавляются новые объекты (описания ошибок).
AD>errs меняется, но потом тут же уничтожается. В чем смысл? Почему get_errors*() возвращает объект, а не ссылку на объект долгоживущий?
Да, errs меняется, потом уничтожается. Но в случае
Потому что объекты, возвращаемые get_errors_without_limits и get_errors_with_limits, внутри себя хранят только указатель на ctx, которому они все передают.
То есть get_errors_without_limits возвращает объект, который просто передает все, что в него засовывают, в свой родительский объект (ctx).
А get_errors_with_limits возвращает объект, который сначала проверяет ограничения, а потом передает добавляемые данные в свой родительский объект (ctx).
-----------
Я тут посмотрел на свою писанину... Сдается мне, начальное решение (с передачей по ссылке) было нормальным.
А то что оно не собирается в Conformance Mode=Yes, это проблемы этого Mode. Меня никто насильно его включать не заставляет
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: Передача объекта, возвращаемого функцией, в другую фу
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>А то что оно не собирается в Conformance Mode=Yes, это проблемы этого Mode. Меня никто насильно его включать не заставляет
то что оно собирается в принципе -- это следствие того что когда-то майкрософт забил на стандарт.
другие компиляторы это не соберут.
если очень хочется, то или сделай add_current_errors шаблонным add_current_errors(TErr&&),
или в базу добавь метод, и вручную вызывай его:
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Есть интерфейс t_errors. КД>У него две реализации — t_errors_without_limits и t_errors_with_limits КД>Есть два метода, возвращающие экземпляры этих реализацией: КД>Теперь есть утилита, работающая с t_errors:
КД>
КД>void add_current_errors(t_errors& errs); //errs внутри не запоминается.
КД>
КД>Все компилируется (VC++) и работает как и ожидается. КД>При включенном 4-ом уровне предупреждений, компилятор предупреждает, что нельзя передавать по ссылке результат метода. КД>Когда включаешь режим 'совместимости/соответствия' (Conformance Mode=Yes), компилятор отказывается компилировать.
Да добавь просто перегрузку для rvalue ссылки и всех делов:
void add_current_errors(t_errors& errs); //errs внутри не запоминается.void add_current_errors(t_errors&& errs) { add_current_errors(errs); }
--
Не можешь достичь желаемого — пожелай достигнутого.
, ошибку компиляции можно задавить с помощью *&. Но вылезут предупреждения 4-го уровня:
add_error(*&ctx.get_errors_without_limits(),1); //warning C4238: nonstandard extension used: class rvalue used as lvalue
add_error(*&ctx.get_errors_with_limits(),2); //warning C4238: nonstandard extension used: class rvalue used as lvalue
Можно переделать add_error, чтобы он получал указатель на errs. Тоже компилируется с предупреждениями 4-го уровня:
void add_error(t_errors* errs,int const errCode);
//...
add_error(&ctx.get_errors_without_limits(),1); //warning C4238: nonstandard extension used: class rvalue used as lvalue
add_error(&ctx.get_errors_with_limits(),2); //warning C4238: nonstandard extension used: class rvalue used as lvalue
//...
Как по мне, начальный вариант со ссылкой выглядел лучше.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>Нет, const тут не нужен, потому что в errs добавляются новые объекты (описания ошибок).
КД>t_errors — это интерфейс формируемой коллекции ошибок.
Передавай тогда по значению, и меняй внутри как хочешь.
void add_current_errors(t_errors errs);
Re[4]: Передача объекта, возвращаемого функцией, в другую функц
КД>>Нет, const тут не нужен, потому что в errs добавляются новые объекты (описания ошибок). КД>>t_errors — это интерфейс формируемой коллекции ошибок.
I>Передавай тогда по значению, и меняй внутри как хочешь. I>void add_current_errors(t_errors errs);
Ну и будет срезка типа. А если t_errors — чисто абстрактный класс, то и вовсе ошибка компиляции.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Передача объекта, возвращаемого функцией, в другую функц
Здравствуйте, Коваленко Дмитрий.
Если я правильно понял, то сами реализации "знают" о ctx, и их методы сами эти реализации не меняют, а меняют в самом ctx.
Почему бы не передать по константной ссылке эти реализации и сами методы не сделать константными?
Можно привести аналогию с указателями. Указатель на константу и константный указатель на не-константу — разные вещи. В вашем случае реализация — это условный константный указатель на не константный
объект ctx, поэтому ее методы по отношению к самой себе — константны.