Consider:
template <typename T>
struct C {
std::vector<int> f(const T &t) const {
return t.f();
}
};
T::f
must compute the required vector. However, some T
's pre-compute the vector and we would like to avoid creating a copy in such a case. Here is my attempt:
struct A {
std::vector<int> f() const {
std::vector<int> res{10, 20, 30}; // computing the vector.
return res;
}
};
struct B {
const std::vector<int> &f() const {
return v_; // returning reference to pre-computed vector.
}
private:
std::vector<int> v_{1, 2, 3};
};
template <typename T>
struct C {
const std::vector<int> &f(const T &t) const {
return t.f();
}
};
int main() {
using T = B; // For A, we get an error about returning reference to a local.
C<T> c;
T t;
c.f(t);
return 0;
}
As the comment in main
indicates, for T=A
, the above code is in error as it is returning a reference to the local variable. How can I accommodate for both T=A
and T=B
, such that the pre-computed vector B::v_
does not get copied?
Make C::f
return the exact same type as T::f
, by using decltype
:
template <typename T>
struct C {
auto f(const T &t) const -> decltype(t.f()) {
return t.f();
}
};
This will return by value when T = A
, and by const&
when T = B
.