Я боролся со следующим примером кода с gcc 7.3 и c ++ 17: https://wandbox.org/permlink/UT3RR9jgRmr3VBWv
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
struct Y {
Y ( int const & s ) : y(s) { std::cout << "construct y\n"; }
Y ( Y const & yi ) : y(yi.y) { std::cout << "copy y\n"; }
Y ( Y && yi ) noexcept : y(yi.y) { std::cout << "move y\n"; }
int y;
};
struct X {
X ( Y const & yi ) : x(yi.y) { std::cout << "construct x\n"; }
X ( X const & xi ) : x(xi.x) { std::cout << "copy x\n"; }
X ( X && xi ) noexcept : x(xi.x) { std::cout << "move x\n"; }
int x;
};
int main () {
std::vector<Y> vy{1};
std::vector<X> vx;
vx.reserve(vy.size());
std::cout << "begin transform\n";
std::transform(begin(vy), end(vy), std::back_inserter(vx), [] (auto const & y) { return y; });
}
Вывод
construct Y
copy Y
begin transform
copy Y
construct X
move X
Почему эта вторая копияY (в преобразовании) случится?Я могу избавиться от него, установив тип возвращаемого значения унарной лямбды на ссылку
-> auto const &
Я думал, что встроенная природа лямбда-оператора () и / или копирования elision позаботятся о «бесполезном»"копия.
РЕДАКТИРОВАТЬ: Как объяснил Барри, ответ заключается в том, что стандарт запрещает исключение копирования возвращений аргументов функции.