Я бы хотел вывезти членов временного персонала без ненужного перемещения или копирования.
Предположим, у меня есть:
class TP {
T _t1, _t2;
};
Я бы хотел получить _t1
и _t2
от TP()
. Возможно ли это без копирования / перемещения участников?
Я пытался с кортежами и пытался «переслать» (я не думаю, что это возможно) участников, но лучшее, что я мог получить, это движение или члены, умирающие немедленно.
На следующей игровой площадке использование B::as_tuple2
приводит к тому, что участники умирают слишком рано, если только результат не привязан к типу не-ref, тогда члены перемещаются. B::as_tuple
просто перемещается безопасно с auto
на стороне клиента.
Я полагаю, что это должно быть технически возможно, поскольку временные модули немедленно умирают, и член действительно умирает, пока они могут связываться с переменными на вызывающем сайте (я ошибаюсь?), И структурированное связывание аналогичной структуры работает, как предполагалось.
Можно ли продлить / передать жизнь элемента на внешнюю переменную или исключить перемещение / копирование? Мне это нужно с версией c ++ 14, но я не смог заставить ее работать и на c ++ 17, поэтому мне интересны оба варианта.
Детская площадка
#include <tuple>
#include <iostream>
using std::cout;
class Shawty {
/**
* Pronounced shouty.
**/
public:
Shawty() : _id(Shawty::id++) {cout << _id << " ctor\n"; }
Shawty(Shawty && s) : _id(Shawty::id++) { cout << _id << " moved from " << s._id << "\n"; }
Shawty(const Shawty & s) : _id(Shawty::id++) { cout << _id << " copied from " << s._id << "\n"; }
Shawty& operator=(Shawty && s) { cout << _id << " =moved from " << s._id << "\n"; return *this;}
Shawty& operator=(Shawty & s) { cout << _id << " =copied from " << s._id << "\n"; return *this;}
~Shawty() {cout << _id << " dtor\n"; }
int _id;
static int id;
};
int Shawty::id = 0;
class B {
public:
auto as_tuple() && {return std::make_tuple(std::move(_s1), std::move(_s2));}
auto as_tuple2() && {return std::forward_as_tuple(std::move(_s1), std::move(_s2));}
private:
Shawty _s1, _s2;
};
struct S {
Shawty _s1, _s2;
};
int main() {
std::cout << "----------\n";
auto [s1, s2] = B().as_tuple2();
std::cout << "---------\n";
auto tpl1 = B().as_tuple2();
std::cout << "----------\n";
std::tuple<Shawty, Shawty> tpl2 = B().as_tuple2();
std::cout << "----------\n";
std::cout << std::get<0>(tpl1)._id << '\n';
std::cout << std::get<1>(tpl1)._id << '\n';
std::cout << std::get<0>(tpl2)._id << '\n';
std::cout << std::get<1>(tpl2)._id << '\n';
std::cout << s1._id << '\n';
std::cout << s2._id << '\n';
std::cout << "--struct--\n";
auto [s3, s4] = S{};
std::cout << s3._id << '\n';
std::cout << s4._id << '\n';
std::cout << "----------\n";
return 0;
}