对 std::vector 使用嵌套 [ ] 操作

Using nested [ ] operations for std::vector

本文关键字:嵌套 操作 std vector      更新时间:2023-10-16

我对C++很陌生,我尝试过寻找答案并运行测试,但很多时候我都无法弄清楚导致特定行为的原因。 我的问题与使用嵌套[ ]运算符访问或修改循环中的元素有关 - 示例:

//Declare
std::vector<int> a1 {10,20,30,40} ;
std::vector<int> a2 {2,3} ;
int S2 = a2.size() ; 
//Loop
for(int i = 0 ; i < S2 ; i++){
a1[a2[i]] = a1[a2[i]] + 5000 ;
}

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

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

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

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

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

如果需要范围检查并且性能不重要,则可以考虑使用std::vectorat运算符

for(const auto & index :a2) {
a1.at(index) += 5000;
}

at函数自动检查 n 是否在向量中有效元素的范围内,如果不是(即,如果 n 大于或等于其大小(,则引发out_of_range异常。这与成员运算符 [] 相反,成员运算符 [] 不检查边界。

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

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

这是完全正确的。

但实际上,您只想迭代标准容器的元素。C++允许该用例的基于范围 for 语句

for (index: a2) {
a1[index] += 5000;
}

我发现它更具可读性,即使它主要是品味问题......

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

对我来说看起来还不错。无需创建a2[i]的显式副本。

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

我还建议将循环变量i转换为std::size_t(如果您想完美,请使用++i而不是i++:(。

在现代C++中,您还可以使用基于范围的 for,这样您就不必使用显式索引变量来访问a2值:

for (auto indexFromA2 : a2)
a1[indexFromA2] += 5000;

这不太容易出错,因为您必须编写更少的逻辑来管理元素访问(并且不必拼写出类型(。

我会以某种方式确保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 ;
}