允许预先计算和即时计算的结果

Allowing both pre-computed and computed-on-the-fly results

考虑:

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=AT=B,这样预先计算的向量 B::v_ 就不会被复制?

使用 decltype:

使 C::f return 与 T::f 完全相同
template <typename T>
struct C {
    auto f(const T &t) const -> decltype(t.f()) {
        return t.f();
    }
};

这将 return T = A 时按值 ,在 T = B 时按 const&

wandbox example

您的尝试没有测试它应该做的事情。要使 pre-computed 结果有用,它们需要持久。一个 class 需要同时进行计算和存储。

例如,

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 定义函数的域。