考虑:
template <typename T>
struct C {
std::vector<int> f(const T &t) const {
return t.f();
}
};
T::f
必须计算所需的向量。但是,有些T
预先计算了向量,我们希望避免在这种情况下创建副本。这是我的尝试:
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;
}
正如main
中的注释所示,对于T=A
,上面的代码是错误的,因为它返回对局部变量的引用。我如何适应T=A
和T=B
,以便不会复制预先计算的向量B::v_
?
答案 0 :(得分:4)
使用C::f
使T::f
返回与decltype
完全相同的类型:
template <typename T>
struct C {
auto f(const T &t) const -> decltype(t.f()) {
return t.f();
}
};
这将在T = A
时以值返回,在const&
时返回T = B
。
答案 1 :(得分:2)
您的尝试不是测试它应该是什么。为了使预先计算的结果有用,它们必须是持久的。一个类需要同时进行计算和存储。
例如,
struct A {
std::vector<int> const & f() const {
if ( v_.empty() ) {
v_ = {10, 20, 30}; // computing the vector.
}
return v_;
}
private:
mutable std::vector<int> v_;
};
另一种架构是将所有结果存储在一个std::map< X, std::vector >
(或unordered_map
)中,如果有一些类型X
定义了该函数的域。