传递大型const对象的向量的正确方法

时间:2019-07-02 12:03:18

标签: c++

我想将不能在函数内部更改的巨大对象的向量传递给函数。显然,我想避免复制这些对象。另外,我不想使用指针。我尝试使用reference_wrapper,但它给出了错误。

该函数通常也会用括号括起来的此类对象列表进行调用(当它们是动态构建的时)。

具有指针的MWE:

#include <iostream>
#include <vector>

using namespace std;

struct HugeObject {
    int value = 42;
    // large chuck of data inside
};

HugeObject operator*(const HugeObject &a, const HugeObject &b) {
    return {a.value * b.value};
}

HugeObject op2(const HugeObject &a, const HugeObject &b) {
    HugeObject ret_obj;
    // calculate return object based on a and b
    return ret_obj;
}

HugeObject f(const HugeObject &a, const HugeObject &b, const HugeObject &c) {
    HugeObject ret_obj;
    // calculate return object based on a, b, and c
    return ret_obj;
}

double do_some_calculation(const vector<HugeObject *> &objects) {
    double ret_val = 0.0;
    // do some calculation on objects
    return ret_val;
}

int main() {
    vector<HugeObject> a{{33}, {666}, {32}, {22}, {735}, {0}, {-123}};
    vector<HugeObject *> subset_1{&a[0], &a[3], &a[4]};
    vector<HugeObject *> subset_2{&a[2], &a[4]};

    cout << do_some_calculation(subset_1) << endl;
    cout << do_some_calculation(subset_2) << endl;
    cout << do_some_calculation({&a[0], &a[1]}) << endl;

    // I would like also to call do_some_calculation() on list constructed in place, something like this:
    cout << do_some_calculation({a[0], a[1] * a[2], op2(a[0], a[4]), f(a[0], a[1], a[2])}) << endl; // obviously, error

    HugeObject b = a[1] * a[2],
            c = op2(a[0], a[4]),
            d = f(a[0], a[1], a[2]);
    cout << do_some_calculation({&a[0], &b, &c, &d}) << endl; // compiles but looks ugly

    return 0;
}

在上一次调用中,由操作(或函数)构造的对象仅使用一次,因此我不在乎它们-但我希望a[0]保持不变。当然,我可以将a[1] * a[2]op2(a[0], a[4])f(a[0], a[1], a[2])的每个命名为变量(源代码的末尾),然后在调用中使用对它们的引用,但这会使代码看起来更加丑陋。

1 个答案:

答案 0 :(得分:1)

您已经将向量作为const引用传递了,因此尚不清楚为什么还要包裹元素。

对于第二个调用,我宁愿将算法重构为:

template <typename IT>
double do_some_calculation_with_multiplied_elements(IT begin, IT end, IT mult_begin, IT mult_end) {
    double ret_val = 0.0;
    // multiply mult_begin up to mult_end and use the result
    return ret_val;
}

如此:

cout << do_some_calculation({a[0], a[1] * a[2]}) << endl;

将成为:

cout << do_some_calculation_with_multiplied_elements(a.begin(),a.begin()+1, a.begin()+2, a.end()) << endl;