对std::vector使用嵌套[]操作 我对C++很陌生,我已经尝试寻找这个答案和运行测试,但是很多时候我都很难弄清楚是什么导致了特定的行为。 我的问题涉及使用嵌套的[]运算符访问或修改循环中的元素-示例: //申报 std::向量a1{10,20,30,40}; std::向量a2{2,3}; int S2=a2.2尺寸; //环路 forint i=0;i

对std::vector使用嵌套[]操作 我对C++很陌生,我已经尝试寻找这个答案和运行测试,但是很多时候我都很难弄清楚是什么导致了特定的行为。 我的问题涉及使用嵌套的[]运算符访问或修改循环中的元素-示例: //申报 std::向量a1{10,20,30,40}; std::向量a2{2,3}; int S2=a2.2尺寸; //环路 forint i=0;i,c++,std,stdvector,C++,Std,Stdvector,这样可以吗?我不仅要求在共同的实践,而且在效率方面和任何其他潜在的因素,我需要考虑。 我是否应该首先在循环中的临时变量中存储[I],然后使用它修改向量a2中的元素 我知道这可能不是最好的结构,我应该使用其他数据结构来做这类事情,但我只想了解这是否正常,或者它是否会导致一些未定义的行为。我会在尝试访问a1中定义的元素之前,以某种方式确保a2中定义的a1中的元素确实存在,否则你就出界了 但是对于嵌套的[],这很好,不需要创建a2的另一个副本来访问a1。编译器正在从内到外展开表达式 您仍然可以稍微简化

这样可以吗?我不仅要求在共同的实践,而且在效率方面和任何其他潜在的因素,我需要考虑。 我是否应该首先在循环中的临时变量中存储[I],然后使用它修改向量a2中的元素


我知道这可能不是最好的结构,我应该使用其他数据结构来做这类事情,但我只想了解这是否正常,或者它是否会导致一些未定义的行为。

我会在尝试访问a1中定义的元素之前,以某种方式确保a2中定义的a1中的元素确实存在,否则你就出界了

但是对于嵌套的[],这很好,不需要创建a2的另一个副本来访问a1。编译器正在从内到外展开表达式

您仍然可以稍微简化代码

 //Declare
 std::vector<int> a1 {10,20,30,40} ;
 std::vector<int> a2 {2,3} ;

 //Loop
 for(int i = 0 ; i < a2.size() ; i++){
          if(a1.size()-1 < a2[i]){break;}
          a1[a2[i]] += 5000 ;
 }

在尝试访问a1中的元素之前,我会以某种方式确保a2中定义的a1中的元素确实存在,否则将超出范围

但是对于嵌套的[],这很好,不需要创建a2的另一个副本来访问a1。编译器正在从内到外展开表达式

您仍然可以稍微简化代码

 //Declare
 std::vector<int> a1 {10,20,30,40} ;
 std::vector<int> a2 {2,3} ;

 //Loop
 for(int i = 0 ; i < a2.size() ; i++){
          if(a1.size()-1 < a2[i]){break;}
          a1[a2[i]] += 5000 ;
 }

我看没问题。不需要创建a2[i]的显式副本

我看到的唯一问题是[]内的参数类型应该是std::size\u t而不是int。这些整数类型包含不同的值范围,虽然std::size\u t是无符号整数类型,但int是有符号整数。注意使用负索引或超过最后一个元素的索引可能会由于越界访问而导致未定义的行为。但是,如果您可以保证a2中的值始终是a1的有效索引,那么这些int值将隐式转换为std::size_t,并且一切正常,这在您问题中的代码示例中似乎就是这样

我还建议将循环变量I转换为std::size\t,如果您想变得完美,请使用++I而不是I++:

在现代C++中,还可以使用基于范围的,因此,您根本不需要使用显式索引变量来访问A2值:

对于自动索引罗马2:a2 a1[indexFromA2]+=5000;
这不太容易出错,因为您必须编写更少的逻辑来管理元素访问,并且不必详细说明类型。

在我看来没问题。不需要创建a2[i]的显式副本

我看到的唯一问题是[]内的参数类型应该是std::size\u t而不是int。这些整数类型包含不同的值范围,虽然std::size\u t是无符号整数类型,但int是有符号整数。注意使用负索引或超过最后一个元素的索引可能会由于越界访问而导致未定义的行为。但是,如果您可以保证a2中的值始终是a1的有效索引,那么这些int值将隐式转换为std::size_t,并且一切正常,这在您问题中的代码示例中似乎就是这样

我还建议将循环变量I转换为std::size\t,如果您想变得完美,请使用++I而不是I++:

在现代C++中,还可以使用基于范围的,因此,您根本不需要使用显式索引变量来访问A2值:

对于自动索引罗马2:a2 a1[indexFromA2]+=5000;
这不太容易出错,因为您必须编写更少的逻辑来管理元素访问,并且不必详细说明类型。

这是完全正确的

但实际上,您只需要迭代标准容器的元素。C++允许使用范围为语句的用例:

for (index: a2) {
    a1[index] += 5000;
}
我发现它更具可读性,即使它主要是一个品味的问题


免责声明:此代码不控制a2元素作为a1索引的有效性。

这是完全正确的

但实际上,您只需要迭代标准容器的元素。C++允许使用范围为语句的用例:

for (index: a2) {
    a1[index] += 5000;
}
我发现它更具可读性,即使它主要是一个品味的问题


免责声明:此代码不控制a2元素作为a1索引的有效性。

我是有限元计算软件的开发人员

我们使用这种技术来访问元素中的值。它帮助我们节省大量内存

但是:要知道这会破坏你的健康 e地点。如果可以避免的话,不要在重循环中使用它

如果您需要一个范围检查和性能并不重要,您可以考虑使用STD的AT运算符::vector < /p> at函数自动检查n是否在向量中有效元素的范围内,如果n不在有效元素的范围内,即如果n大于或等于其大小,则抛出超出范围异常。这与不检查边界的成员运算符[]相反

此外,考虑使用基于范围的循环

 //Loop
 for(const auto & index :a2) {
      a1[index] += 5000;
 }

我是一个有限元计算软件的开发者

我们使用这种技术来访问元素中的值。它帮助我们节省大量内存

但是:请注意,它会破坏缓存位置。如果可以避免的话,不要在重循环中使用它

如果您需要一个范围检查和性能并不重要,您可以考虑使用STD的AT运算符::vector < /p> at函数自动检查n是否在向量中有效元素的范围内,如果n不在有效元素的范围内,即如果n大于或等于其大小,则抛出超出范围异常。这与不检查边界的成员运算符[]相反

此外,考虑使用基于范围的循环

 //Loop
 for(const auto & index :a2) {
      a1[index] += 5000;
 }

这一点正如文章所述,但它依赖于一个不言而喻的假设,即a2中的每个元素都是非负的,并且小于a1的大小。循环中的行也可以使用+=编写,尽管任何自尊心强的编译器都会生成相同的代码。这与发布的一样有效,但它依赖于一个不言而喻的假设,即a2中的每个元素都是非负的,并且小于a1的大小。循环中的行也可以使用+=编写,尽管任何自尊心强的编译器都会生成相同的代码。感谢您的评论,在我的情况下,绑定检查是不必要的,因为我在插入a2之前直接计算a2中的所有元素,这样,在将无效索引输入向量之前将其过滤掉。感谢您的评论,在我的情况下,无需进行边界检查,因为我在插入a2中的所有元素之前直接计算它们,这样,在将无效索引输入向量之前将其过滤掉。就最终结果而言,这个编译会比我的循环标准更有效吗?我非常喜欢你的方法,因为它让我想起了R子集方法。编译器将使用传统的for循环实现基于范围的for循环。这意味着您的代码和Serge的代码将编译成相同的二进制文件,它们将执行相同的操作。就最终结果而言,这种编译会比我的循环标准更有效吗?我非常喜欢你的方法,因为它让我想起了R子集方法。编译器将使用传统的for循环实现基于范围的for循环。这意味着您的代码和Serge的代码将编译成相同的二进制文件,它们的性能相同。