Допустим, у меня есть следующий простой класс Vector:
template <class N>
class Vector<N>
{
public:
std::array<int, N> a;
};
Моя первая попытка double
выглядит следующим образом:
template <class N>
Vector<N>&& double1(Vector<N>&& x)
{
for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
return static_cast<Vector<N>&&>(x);
}
Сначала все выглядит нормально, но если яdo:
auto x&& = double1(makeVector(1,2,3))
У меня будут ссылки на временные проблемы.
Моя вторая попытка следующая:
template <class N>
Vector<N> double2(Vector<N>&& x)
{
for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
return x;
}
К которой, похоже, нет вышеуказанной ссылкик временной проблеме, но делает то, что я считаю ненужным перемещением / копированием по возвращении.
Я мог бы избежать как ссылки на временные проблемы, так и дополнительных перемещений / копий, выполнив следующие действия:
template <class N>
void double3(Vector<N>& x)
{
for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
}
Но тогда я должен внести изменения в аргумент, который я считаю немного грязным.Мне также придется назвать временные имена.
Моя последняя идея заключалась в следующем:
template <class N>
Vector<N> double4(Vector<N> x)
{
for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
return x;
}
Что позволило бы избежать всех копий, если параметр был сохранен в том же месте, что и результат,но я не уверен, как это сделать.
В основном я ищу двойную функцию, которая имеет следующие свойства:
(1) Нет ссылок на временные проблемы при назначении с авто.
(2) Нет копий при передаче временного.
(3) Не изменяет аргумент при передаче временного.
У кого-нибудь есть идеи, как соединить эти три вещи вместе?
Редактировать
Возможно, проще говоря, это поведение, которое я хочу.
(1) Если аргумент является временным, изменитеон на месте.
(2) В противном случае сделайте копию.