【问题标题】:how to pass an array with different sizes to my c++ function?如何将不同大小的数组传递给我的 c++ 函数?
【发布时间】:2018-09-14 01:22:29
【问题描述】:

我不确定这是否可行,但我对想法持开放态度。

我有一个 c++ 函数。它对用户定义为输入的数组进行一些计算,并将生成两个输出值。我们称它为“myfunction”,它看起来像这样:

void myfunction(double array1[18],double array[9],double array[2],double *output1, double *output2)

我想让这个函数更通用,以便它能够接收不同大小的数组。意思是,我希望这个函数的用户能够定义其他大小的数组输入。

例如,

void myfunction(double array1[81],double array[27],double array[3],double *output1, double *output2)

从数学上讲,“myfunction”能够计算出准确的输出,尽管数组大小。我不想复制“myfunction”,因为用户可以将总共 5 组不同的数组大小定义为输入。

有什么想法吗?提前谢谢你

【问题讨论】:

  • 看看std::vectorstd::array
  • void myfunction(double array1[18],double array[9],double array [2],double *output1, double *output2) -- 前三个参数是 not 数组。该声明与此声明完全相同:void myfunction(double *array1, double *array, double *array, double *output1, double *output2);。传递的数组衰减为一个指针——这种声明形式的所有大小信息都丢失了。
  • 添加到@KhouriGiordano,通过引用接受std::vector(或const,当您不打算修改它时)将具有大致相同的性能,并允许您检查@987654327每个输入的@ 以确定您需要循环的内容。
  • 计划A:用户std::vector。 B 计划(如果你必须使用一维数组):根本不声明大小:void myfunction(double *array1,double *array2,double *array3,double *output1, double *output2)
  • 在编译时数组大小是否已知?以及如何计算输出长度?

标签: c++ arrays function input


【解决方案1】:

您可以传递std::vector 或使用template

template <std::size_t N1, std::size_t N2, std::size_t N3> // and so on...
void work_with_arrays(double (&arr1)[N1], double (&arr2)[N2], double (&arr3)[N3]){
    std::cout << "First arr of a size: " << N1 << "\n";
    std::cout << "Second arr of a size: " << N2 << "\n";
    std::cout << "Third arr of a size: " << N3 << "\n";
};

int main() {
    double something[32];
    double fewer[13];
    double maybe_byte[8];

    work_with_arrays(something, fewer, maybe_byte);
}

代码输出:

First arr of a size: 32
Second arr of a size: 13
Third arr of a size: 8

说明:

应该知道T[] 类型的参数(T 是任何类型)衰减T*。如果我们正在处理一个指向数组的指针,我们没有关于它的长度的信息,这是非常不幸的,因为固定长度数组的长度在编译时是已知的,并且在我们使用它们的任何地方都可以看到。

大家也应该知道函数模板不是函数。它是用于创建函数的模板。对于上面示例中使用的每组不同的N#,都会生成一个函数供我们使用。

衰减问题的解决方法是什么?

我们应该将一个引用传递给T[],而不是传递一个原始的T[]。这样类型不会衰减并且数组的大小将是已知的。

语法?

你会注意到T (&amp;name)[some_size] 看起来至少很奇怪。括号是必需的,因为普通的T &amp;name[size] 将被解释为T&amp; name[size],这是一个引用数组,而不是对数组的引用

结论:

能够检测作为参数传递的数组的大小,我们不想将自己局限于一两种情况 - 我们希望覆盖所有情况,所以我们使用template 生成具有所需值的 N# 的函数。

【讨论】:

  • 最好添加细节,例如什么是“double (&arr1)[N1]”以及如何轻松理解“新贡献者”
  • @Swapnil 我通过添加对选定问题的解释来编辑我的答案
【解决方案2】:

您可以让您的函数接受vector,这是一个“动态调整大小的数组”。您可以对其进行迭代,或根据需要获取其大小。见其docs

#include <vector>
using std::vector;  // I'm too lazy to prepend std:: as needed.
void myfunction(const vector<double>& array1, 
                const vector<double>& array2,
                const vector<double>& array3, 
                vector<double>& output1, vector<double>& output2) {

}

如果这不可能,那么让它接受指示数组大小的额外参数。

void myfunction(double *array1,
                double *array2, 
                double *array3,
                int size1,
                int size2,
                int size3,
                double *output1, 
                double *output2) {

}

但这真的很难看。只需选择第一个选项。

【讨论】:

  • 第二种方法不仅“丑”,而且如果尺寸不正确,客户很容易出错。 vector 通过使用 vector::size() 函数知道它的大小,因此永远不会是不正确的。
  • @PaulMcKenzie 完全同意。然而,实际上,有一些平台或约束有时会禁止使用复杂的数据结构(尽管向量不是那么复杂)并且有时会处理无法轻松重构的遗留代码,所以这是一个非常绝望的选项。
  • 在这些情况下,如果 C99 可用,最好使用具有灵活数组成员的结构。
  • @CinderBiscuits 是的。忘了那个。事实上,这带来了另一个选项,即模板专门化一个以std::array 作为参数的函数。基本上@Fureeish 没有原始指针的答案。
猜你喜欢
  • 2018-04-25
  • 2011-03-04
  • 1970-01-01
  • 2017-07-26
  • 2011-05-24
  • 2013-05-11
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多