允许预先计算和计算中的结果

时间:2017-02-19 15:19:25

标签: c++ c++11 generic-programming const-reference

考虑:

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_

2 个答案:

答案 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

wandbox example

答案 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定义了该函数的域。