简体   繁体   English

C++ 基于范围的 for 循环和元素副本

[英]C++ range-based for loop and copy of element

I want to generate all subsets of a given vector:我想生成给定向量的所有子集:

vector<vector<int>> findSubsets(const vector<int> &nums) {
        vector<vector<int>> subsets;
        subsets.push_back(vector<int>{}); //empty set
        for (auto current_num : nums)
        {
            //add current_num to all existing subsets
            int n = subsets.size();
            for (int i = 0; i < n; i++) {
                vector<int> set(subsets[i]);
                set.push_back(num);
                subsets.push_back(set);
            }
        }
        return subsets;
    }

I wanted to use a range based for loop for iterating over all subsets it gives a different result:我想使用基于范围的 for 循环来迭代所有子集,它给出了不同的结果:

vector<vector<int>> findSubsets(const vector<int> &nums) {
        vector<vector<int>> subsets;
        subsets.push_back(vector<int>{}); //empty set
        for (auto current_num : nums)
        {
            //add current_num to all existing subsets
            for (vector<int> subset : subsets)
            {
                subset.push_back(current_num);
                subsets.push_back(subset);
            }
        }
        return subsets;
    }

But this does not do what I intended.但这并不符合我的意图。 What am I missing?我错过了什么?

As mentioned in the comment by @Fureeish one problem with the second version is inserting to the subsets vector while iterating over the subsets vector.正如@Fureeish 在评论中提到的,第二个版本的一个问题是在迭代子集向量时插入子集向量。

for (vector<int> subset : subsets)
 {
   subset.push_back(current_num);
   subsets.push_back(subset);  // Should not modify vector while iterating on it
 }

The range statement expands to something like: range 语句扩展为:

{

    auto && __range = range_expression ;
    for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {

        range_declaration = *__begin;
        loop_statement
    }
} 

The __end expression is expanded before the iterations. __end 表达式在迭代之前展开。 For a vector this could be calculating the address at vector.data[size].对于向量,这可能是计算 vector.data[size] 处的地址。 If the loop pushes new elements into the vector, the __end expression is no longer correct.如果循环将新元素推入向量中,则 __end 表达式不再正确。

If you iterated over a copy of the vector instead, the range statement would work.如果您迭代向量的副本,则范围语句将起作用。 For example:例如:

    for (vector<int> subset : vector<vector<int>>(subsets))
    {
        subset.push_back(current_num);
        subsets.push_back(subset);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM