将向量传递和返回到 C++ 中的函数

Posted

技术标签:

【中文标题】将向量传递和返回到 C++ 中的函数【英文标题】:passing and returning vectors to a function in C++ 【发布时间】:2015-11-09 16:38:57 【问题描述】:

我有一个函数:

void computeC(array3D fp, double& C) 
C = 0.0;
for (int x = 0; x < M; ++x) 
    for (int y = 0; y < N; ++y) 
        for (int i = 0; i < 5; ++i) 
            C += fp[x][y][i];
        
    


这里的变量 fp 和 C 定义为:

typedef std::vector<double> array1D;
typedef std::vector<array1D> array2D;
typedef std::vector<array2D> array3D;
array2D C(M, array1D(N, 0));
array3D fp(M, array2D(N, array1D(5, 0.0)));

函数被称为:

computeC(fp, C);

当我执行主代码时,出现以下错误:

vect.cpp:9:22: error: invalid initialization of reference of type 'double&' 
from expression of type 'array2D aka std::vector<std::vector<double> >'

vect.hpp:130:6: error: in passing argument 2 of 'void computeRho(array3D, double&)'

我该如何解决这个问题?

【问题讨论】:

令人惊讶的是,double&amp;array2D 的类型不同。 您是否阅读了错误信息?它准确地说明了问题所在。 void computeC(array3D fp, double&amp; C) 即使你得到第二个参数,你也应该通过引用而不是值来传递第一个参数。 PaulMckenzie..尝试你的建议仍然是同样的错误。 我的建议与不必要的 3d 矢量复制有关。如果您通过引用传递它,则副本不会完成。 【参考方案1】:

编译器信息很清楚。您尝试传递给函数的第二个参数的类型与声明的参数类型匹配。参数的类型是double&amp;,但您尝试传递array2Darray2D 不是 double,所以你不能把它传递给函数。

要解决这个问题,请将C 定义为double

但是 array2D 是双精度向量的向量。如何再次将 C 定义为双精度?

您可以通过删除定义 array2D C(M, array1D(N, 0)); 并将其替换为 double C = 0.0; 来做到这一点

关于以向量作为输入和输出参数的函数定义的任何其他想法?

是的,这是另一种可能的方法。您可以代替定义一个接受double&amp; 作为参数的函数,而是实现一个接受array2D&amp; 参数的函数。然后你可以将C 传递给这样的函数。

【讨论】:

但是 array2D 是双精度向量的向量。我怎样才能再次将C 定义为double C 是二维数组,其值会在代码执行过程中发生变化。我在 global scope 中定义了array2D C(M, array1D(N, 0));,我的代码也在其他地方使用。以向量作为输入和输出参数的函数定义还有其他想法吗? @TheCoder C is 2D array 这正是问题所在。如果C 是一个二维数组,那么您根本无法将它传递给不采用二维数组的函数。 完全不清楚你希望代码做什么,所以你必须解释它,@TheCoder。你的函数需要一个double,但你给了它一些其他的东西。你期待什么?当您向我们寻求帮助时,您希望我们做什么 @LightnessRacesinOrbit:代码必须采用 3D 数组(我定义的向量的向量)和 2D 数组(定义的向量的向量)。 2D 数组会在代码执行期间更新,但 3D 数组用于计算 2D 数组。我写了一个函数,这给了我所说的错误。我想删除错误并希望定义我不必更改数组定义而是修改函数的函数。我需要你们的帮助来完成修改或更改现有功能的某些部分,以使代码正常工作。【参考方案2】:

(编辑:在 OP 的 cmets 后更新答案)

这是你要找的东西吗:

typedef std::vector<double> array1D;
typedef std::vector<array1D> array2D;
typedef std::vector<array2D> array3D;

void computeC(array3D& fp, array2D& C) 
    double tmp = 0.0;

    // Calculate sum of element in 3D array
    for (int x = 0; x < M; ++x) 
        for (int y = 0; y < N; ++y) 
            for (int i = 0; i < 5; ++i) 
                tmp += fp[x][y][i];
            
        
    

    // Update the 2D array
    for (int x = 0; x < M; ++x) 
        for (int y = 0; y < N; ++y) 
            C[x][y] = tmp;
        
    


int main()

    array2D C(M, array1D(N, 0));
    array3D fp(M, array2D(N, array1D(5, 0.0)));
    computeC(fp, C);
    return 0;

typedef std::vector<double> array1D;
typedef std::vector<array1D> array2D;
typedef std::vector<array2D> array3D;

void computeC(array3D& fp, array2D& C) 
    for (int x = 0; x < M; ++x) 
        for (int y = 0; y < N; ++y) 
            for (int i = 0; i < 5; ++i) 
                C[x][y] += fp[x][y][i];
            
        
    


int main()

    array2D C(M, array1D(N, 0));
    array3D fp(M, array2D(N, array1D(5, 0.0)));
    computeC(fp, C);
    return 0;

【讨论】:

假定 MN 是在别处定义的非 const double 值。 没关系,但我仍然不明白 OP 想要对 array2D C 做什么以及为什么他不只返回一个双精度数 谁说过全局变量? @LightnessRacesinOrbit - OP 在对另一个答案的评论中写道。 直到它成为问题的一部分或我看不到它的相关性。【参考方案3】:

我认为 StillLearning 的答案最适合您的问题。

也许你可以去掉全局变量,把这个函数分成两个更基本的功能,比如 sumOfElements 和 setElements:

#include <iostream>
#include <vector>

typedef std::vector<double> array1D;
typedef std::vector<array1D> array2D;
typedef std::vector<array2D> array3D;

template< typename T>
double sumOfElements (T & a) 
    double sum = 0.0;
    for ( auto i : a) sum += sumOfElements(i);
    return sum;


template<>
double sumOfElements<array1D> (array1D & a) 
    double sum = 0.0;
    for ( auto i : a) sum += i;
    return sum;


template< typename T >
void setElements ( double val, T & a) 
    for ( auto & i : a) setElements(val,i);


template<>
void setElements<array1D> ( double val, array1D & a) 
    for ( auto & i : a) i = val;


int main() 
    double d;
    array2D b(4,array1D(5,0.1));
    array3D c(3,array2D(4,array1D(5,2.0)));


    d = sumOfElements(c);
    std::cout << "Sum of elements: " << d << std::endl;
    setElements(d,b);
    std::cout << "Now all the elements of the array2D are: " << b[2][3] << std::endl;;

    return 0;

【讨论】:

【参考方案4】:

最后,我得到了结果,并且功能按预期完美运行。谢谢您的帮助。工作功能是:

void computeC(array3D& fp, array2D& C) 
    for (int x = 0; x < M; ++x) 
        for (int y = 0; y < N; ++y) 
         C[x][y] = 0.0
            for (int i = 0; i < 5; ++i) 
                C[x][y] += fp[x][y][i];
            
        
    

【讨论】:

您已按照我的建议正确地将参数类型更改为array2D&amp;。但是你的函数似乎没有对参数做任何事情。 @user2079303:我的函数将 fp 作为输入 3D 数组,将其所有元素求和并将其分配给 C,即 2D 数组。 @Bob__:你能强调或建议修改吗?由于我不是高级用户,因此,如果您可以的话,我需要帮助。 @TheCoder:您通过引用传递了一个名为 C 的 array2D。美好的。然后你声明一个同名的变量 C 作为一个双精度数(这是一个标量,1 数字),将它设置为 0.0 并使用它来累加总和。您没有更改您传递的参数的任何元素,您正在使用其他东西。看看 StillLearnig 写了什么。

以上是关于将向量传递和返回到 C++ 中的函数的主要内容,如果未能解决你的问题,请参考以下文章

将 c++ 向量传递给 python 并返回

从 C++ 中的函数返回向量或数组

c++ 以最佳方式返回结构和向量

C++中的指针和向量

从c ++中的函数返回数组向量[重复]

如何将结构数组从 c++ 传递到 c#?