Я пытаюсь написать функцию, которая возвращает пару объектов, один из которых построить сложнее, чем другой. Этот код приближается к иллюстрации того, что я пытаюсь:

#include<iostream>
#include<tuple>

using namespace std;

struct A {
  int i;
  A(A&& a): i(a.i) { cout << "move-constructing A: "<<a.i<<"\n"; }
  A(int j): i(j) { cout << "int-constructing A: "<<j<<"\n"; }
};
using APair = pair<A,A>;

APair get_As() {
  A a(8);
  return {piecewise_construct, make_tuple(move(a)), make_tuple(10)};
}

int main()
{
  APair As = get_As();
  return 0;
}

Но когда я запускаю это, я вижу двойной ход A, построенный с помощью 8:

int-constructing A: 8
move-constructing A: 8
move-constructing A: 8
int-constructing A: 10

Я понимаю, это потому, что A перемещается в std::tuple, а затем в APair main(). Ясно, что одного хода должно быть достаточно для построения APair, но я не вижу, как бы я это сделал, поскольку кусочный конструктор кажется неизбежным, а это значит, что я также должен предоставить кортеж ... Таким образом, мой вопрос : как это можно сделать одним ходом A?

0
igel 13 Ноя 2020 в 00:37

1 ответ

Лучший ответ

Вы можете использовать std::forward_as_tuple, чтобы избежать лишнего конструктора перемещения:

return {piecewise_construct, std::forward_as_tuple(move(a)), make_tuple(10)};

Демо

Итак, у вас есть std::tuple<A&&> вместо std::tuple<A> (конструкция перемещения).

1
Jarod42 12 Ноя 2020 в 21:45