使整个对象保持不变是否与使整个对象和内部对象保持不变相同?

Is making the whole object constant same as making the whole object and the internal objects constant?

简而言之,问题是以下两个语句是否等价:

const std::vector<std::vector<int>>

const std::vector<const std::vector<int>>

因为,在下面两个代码中,第一个不编译!

code1

#include <vector>

long findMaxSum(const std::vector<const std::vector<int>>& vecs) {

}

int main() {
    std::vector<std::vector<int>> stacks(10,std::vector<int>(10)); //yeah yeah I know stacks is evil!
    for (auto& stack : stacks) {
        for (auto& elem : stack) {
            elem = 4;
        }
    }
    auto t = findMaxSum(stacks);
    return 0;
}

code2

#include <vector>

long findMaxSum(const std::vector<std::vector<int>>& vecs) {

}

int main() {
    std::vector<std::vector<int>> stacks(10,std::vector<int>(10));
    for (auto& stack : stacks) {
        for (auto& elem : stack) {
            elem = 4;
        }
    }
    auto t = findMaxSum(stacks);
    return 0;
}

它们并不完全相同,但您确实无能为力。

如您所见,尝试创建包含 const 元素的 vector 通常会失败。

您可以使外部集合成为 std::array--它对其包含的元素没有那么严格的要求,因此 std::array<const std::vector<whatever>, SIZE> 完全没问题。

另一种可能性是将指针向量传递给 const 向量:

// receive a vector of pointers to const vectors:
int findMaxSum(std::vector<const std::vector<int> *> &outer) {
    std::vector<int> sums;
    std::transform(outer.begin(), outer.end(), 
        std::back_inserter(sums), 
        [](auto v) { return std::accumulate(v->begin(), v->end(), 0); });

    return *std::max_element(sums.begin(), sums.end());
}

int main() { 
    const std::vector<int> a {1, 2};
    const std::vector<int> b {3, 4};

    // pass only the address of each of the component vectors:
    std::vector<const std::vector<int> *> c { &a, &b};
    std::cout << findMaxSum(c) << "\n";
}

这有一个额外的好处,即避免复制每个分量向量只是为了将其传递给函数。如果分量向量很大,这可以是一个重要的考虑因素。