семантика перемещения и return
От: sergii.p  
Дата: 21.06.22 15:23
Оценка: 3 (1) -1
когда я был маленьким, я тоже думал, что не надо писать return std::move(res). Компилятор умеет всякие NRVO. А если и не умеет, то вроде как всё равно должен попытаться переместить.
А недавно столкнулся с тем, что в таком коде

std::string or_throw(std::optional<std::string> v)
{
    return v ? v.value() : throw std::runtime_error("");
}


строка копируется. Надо явно вызывать std::move(v).value(). Хотя ясно (по крайней мере мне) что объект скоро помрёт и его надо по возможности обобрать. Делаем вывод: если значение перед возвратом надо как-то обработать, значит переместить не можем. Идём дальше, такой код почему-то перемещает:

std::optional<std::string> wrap(std::string s)
{
    return s;
}


хотя вроде вызывается промежуточный конструктор. Предыдущие выводы отвергаем, немного усложняем пример. Такой код уже копирует:

std::optional<std::string> not_empty(std::string s)
{
    return !s.empty() ? s : throw std::runtime_error("");
}


Может это слишком сложно для компилятора. Упростим до тривиального:

std::string get_name(Person p)
{
    return p.name;
}


Всё равно копия. Правда уже немного объяснимо — очень похоже на первый пример. В общем, помогите навести порядок в голове.

p.s. может другие компиляторы ведут себя по-другому. Это gcc, оптимизация включена.
Re: семантика перемещения и return
От: σ  
Дата: 21.06.22 15:41
Оценка: 3 (1) +1 -1
SP>помогите навести порядок в голове.

https://timsong-cpp.github.io/cppwp/n4861/class.copy.elision тут всё описано.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.