如何通过引用或指针访问二维矢量

How to access 2D vector by reference or pointer

本文关键字:二维 引用 何通过 指针 访问      更新时间:2023-10-16

我使用的是Visual Studio 2017。我在全局范围内定义了两个2D矢量:

std::vector<std::vector<double>> my_vector1;
std::vector<std::vector<double>> my_vector2;

还有大量的全局常量和参数也在全局范围中定义:

double my_parameter1 = 1;
/* lots of other constants and variables here*/

然后我有一个函数,它需要访问一个向量和特定的全局参数,这取决于传递给函数的参数:

double MakeCalculations(int vector_to_use){
std::vector<std::vector<double>> my_vector;
double my_parameter;     
/*lots of other variables here */
if(vector_to_use == 1){                         //use first vector
my_vector = &my_vector1;                      //doesn't work
/*assigning values for lots of parameters*/
}
else{                                           //use second vector
my_vector = &my_vector2;                      //doesn't work
/*assigning values for lots of parameters*/
}
/*performing calculations with my_vector here*/
}

然后:

int main(){
my_vector1.resize(sizei1, std::vector<double>(sizej1, 0)); //initializing 2D vector
my_vector2.resize(sizei2, std::vector<double>(sizej2, 0)); //initializing 2D vector
/*using function MakeCalculations here alot*/
}

如何根据传递的参数vector_to_use使变量my_vector成为对my_vector1my_vector2的引用?

谢谢

最接近您的问题的解决方案是使用临时指针变量,同时需要对您已经编写的代码进行最少的更改。

std::vector<std::vector<double>>* tmp_ptr;
double my_parameter;     
/*lots of other variables here */
if (vector_to_use == 1) {                         //use first vector
tmp_ptr = &my_vector1;
/*assigning values for lots of parameters*/
}
else{                                           //use second vector
tmp_ptr = &my_vector2;
/*assigning values for lots of parameters*/
}
std::vector<std::vector<double>>& my_vector = *tmp_ptr;
/*performing calculations with my_vector here*/
}

在这一行中,您试图获取my_vector1的地址,并将其填充到向量类型的变量中:

my_vector = &my_vector1;

表达式'&my_myvector1'产生一个指针类型的值,或者更具体地说,std::vector<std::vector<double>>*(注意后面的星号(。一种选择是将"my_vector1"的类型更改为std::vector<std::vector<double>>*的类型,并将对其成员的每次访问更改为使用->语法而不是.

另一种选择是将my_vector作为引用,但在当前代码中这是不可能的,因为您必须在声明时初始化引用类型变量。然而,您可以通过将代码稍微重构为以下内容来实现这一点:

std::vector<std::vector<double>>& my_vector = DetermineVectorToUse(vector_to_use)

DetermineVectorToUse为:

std::vector<std::vector<double>>& DetermineVectorToUse(int vector_to_use)
{
if (vector_to_use == 1)
{
return my_vector1;
}
etc.
}

请注意,vector_to_use的每个值都必须有一个向量,因为您总是必须(或者至少希望(返回对位于函数范围之外的向量的有效引用。

只需将本地变量"my_vector"的类型更改为指针即可。

std::vector<std::vector<double>>* my_vector;

然后,您必须使用->访问变量,如下所示:

std::cout << my_vector->at(0).at(0) << std::endl;

工作版本:

double MakeCalculations(int vector_to_use) {
std::vector<std::vector<double>>* my_vector;
double my_parameter;
/*lots of other variables here */
if (vector_to_use == 1) {                         //use first vector
my_vector = &my_vector1;                      //doesn't work
/*assigning values for lots of parameters*/
}
else {                                           //use second vector
my_vector = &my_vector2;                      //doesn't work
/*assigning values for lots of parameters*/
}
std::cout << my_vector->at(0).at(0) << std::endl;
my_vector->at(0).at(0) = 88;
/*performing calculations with my_vector here*/
return 0;}

这不是为了回答OP问题。

我想补充一点,如果你的2d是固定的,至少一个维度。如果您将其创建为数组的向量类型,则可以拥有像内置数组一样的连续2d数据。

#include <iostream> // cout
#include <vector>   // vector
#include <array>    // array
#include <iomanip>  // fixed, setprecision
constexpr size_t col_c = 10;
size_t row = 5;
using row_t = std::array<double,col_c>;
using vec2d_t = std::vector<row_t>;
auto make_2d_of_row(size_t row) -> vec2d_t {
return vec2d_t(row,row_t{});
}
int main()
{
auto vec1 = make_2d_of_row(row);
auto vec2 = make_2d_of_row(row);
auto init = 0.0;
for (size_t row = 0; row < vec1.size(); ++row) {
for (size_t col = 0; col < col_c; ++col) {
vec1[row][col] = (init += 0.1);
}
}
std::cout << std::fixed << std::setprecision(1);
for (size_t row = 0; row < vec1.size(); ++row) {
for (size_t col = 0; col < col_c; ++col) {
std::cout << vec1[row][col] << " ";
}
std::cout << "n";
}
}

打印

0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 
1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 
2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 
4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 

当然,你也可以像约翰的答案一样,从选择性指针中调用引用。

vec2d_t* tmp_ptr;
....
vec2d_t& my_vector = *tmp_ptr;

godbolt.org/g/ZaqmBs

wandbox.org/permlink/U3ynShvUnqkBYim2