Есть ли способ создать тип A
такой, что:
Дано:
A f(...);
Тогда:
И auto&& a = f(...);
, и const auto& a = f(...);
выдают ошибки компиляции?
Причина этого в том, что в данном случае A
является шаблоном выражения, который содержит ссылки на временные ссылки (которые предоставляются в качестве аргументов для f
), поэтому я не хочу, чтобы время жизни этого объекта было расширено за пределы текущее выражение.
Примечание. Я могу предотвратить возникновение проблемы auto a = f(...);
, просто сделав A
конструктор копирования закрытым, и сделав f(...)
другом A, если потребуется.
Пример кода (ссылка ideone) :
#include <iostream>
#include <array>
template <class T, std::size_t N>
class AddMathVectors;
template <class T, std::size_t N>
class MathVector
{
public:
MathVector() {}
MathVector(const MathVector& x)
{
std::cout << "Copying" << std::endl;
for (std::size_t i = 0; i != N; ++i)
{
data[i] = x.data[i];
}
}
T& operator[](std::size_t i) { return data[i]; }
const T& operator[](std::size_t i) const { return data[i]; }
private:
std::array<T, N> data;
};
template <class T, std::size_t N>
class AddMathVectors
{
public:
AddMathVectors(const MathVector<T,N>& v1, const MathVector<T,N>& v2) : v1(v1), v2(v2) {}
operator MathVector<T,N>()
{
MathVector<T, N> result;
for (std::size_t i = 0; i != N; ++i)
{
result[i] = v1[i];
result[i] += v2[i];
}
return result;
}
private:
const MathVector<T,N>& v1;
const MathVector<T,N>& v2;
};
template <class T, std::size_t N>
AddMathVectors<T,N> operator+(const MathVector<T,N>& v1, const MathVector<T,N>& v2)
{
return AddMathVectors<T,N>(v1, v2);
}
template <class T, std::size_t N>
MathVector<T, N> ints()
{
MathVector<T, N> result;
for (std::size_t i = 0; i != N; ++i)
{
result[i] = i;
}
return result;
}
template <class T, std::size_t N>
MathVector<T, N> squares()
{
MathVector<T, N> result;
for (std::size_t i = 0; i != N; ++i)
{
result[i] = i * i;
}
return result;
}
int main()
{
// OK, notice no copies also!
MathVector<int, 100> x1 = ints<int, 100>() + squares<int, 100>();
// Should be invalid, ref to temp in returned object
auto&& x2 = ints<int, 100>() + squares<int, 100>();
}