имеет конструктора копирования. Как мне правильно вернуть из функции std::future?
Пример:
std::future foo()
{
return promise.get_future();
}
По идеи данный пример компилируется, так как у нас RVO и конструктор копирования вызваться не будет. Но насколько я помню, то только начиная с с++17 гарантируется, что в данном случае будет RVO. А до с++17 я должен по идеи делать std::move ? Чтобы код был переносимым.
Если написать std::move, то RVO работать не будет. Про гарантию RVO - сейчас уточню, когда она появилась...
Да, если мы будем делать move, то оптимизации не будет. Сама оптимизация RVO появилась давно, но вот вроде гарантировать ее в данном случае стал c++17. До с++17 это вроде как на усмотрение компилятора.
Да не, вроде как с 11 стандарта гарантируется в твоем случае: In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a function parameter or a catch clause parameter, and which is of the same class type (ignoring cv-qualification) as the function return type. This variant of copy elision is known as NRVO, "named return value optimization". In the initialization of an object, when the source object is a nameless temporary and is of the same class type (ignoring cv-qualification) as the target object. When the nameless temporary is the operand of a return statement, this variant of copy elision is known as RVO, "return value optimization".
Эй, я и так это сделал!
Вот тут написано: https://en.cppreference.com/w/cpp/language/copy_elision
если я ничего не путаю, в вашем текущем коде выберется удаленный конструктор копирования и ничего не скомпилируется stmt.return#2.sentence-4 the return statement initializes the returned reference or prvalue result object of the (explicit or implicit) function call by copy-initialization from the operand. dcl.init#general-16.6.2.1 If overload resolution is successful, the selected constructor is called to initialize the object, with the initializer expression or expression-list as its argument(s).
нужен std::move, чтобы операнд стал prvalue и конструктор перемещения выиграл у конструктора копирования
Там же написано: A copy operation associated with a return statement can be elided or converted to a move operation if an automatic storage duration variable is returned
В жопу иди
Automatic storage duration - обычная локальная переменная как раз под это попадает
>can be elided и как это помогает?
а вам с каким стандартом нужно быть совместимым?
Агрх, бесит! Это же, фактически, UB. Тут can be, там can be, а что в итоге - никто предсказать не может
где вы UB увидели? в этом случае все диагностируемо на этапе компиляции (ill-formed)
Окей, undefined тут не подходит. Но всё равно выглядит крайне не приятно
promise.get_future() это prvalue выражения типа std::future, соответственно при инициализации результата функции конструктор перемещения выигрывает у конструктора копирования. делать ничего не нужно, все будет работать ссылки на 11 стандарт: https://timsong-cpp.github.io/cppwp/n3337/expr.call#10 https://timsong-cpp.github.io/cppwp/n3337/dcl.init#14 https://timsong-cpp.github.io/cppwp/n3337/dcl.init#16.6.1 механика copy elision не имеет никакого значения в таком вопросе о корректности программы
Ты лучший! @alex_monster15, мы кажется разобрались)
компиляторы согласны https://godbolt.org/z/oYGrG9M16
спасибо за объяснение)
Обсуждают сегодня