如何传递以 "size determined at run time" 作为引用的动态分配数组?

How to pass a dynamically allocated array with "size determined at run time" as a reference?

本文关键字:引用 动态分配 数组 run 何传递 size determined at time      更新时间:2023-10-16

我知道如何将一个常量大小的数组作为引用传递,但我想知道如何将一个可变大小的数组作为对另一个函数的引用传递。任何帮助将不胜感激。谢谢

例如,我有以下代码片段:

void y(int (&arr)[n]) //Gives error
{}
void x(Node * tree, int n)
{
     int arr[n];
     y(arr);
}

我听说我们可以模板化函数并使大小成为模板参数,但我无法这样做。

很简单:不要。请改用std::arraystd::vector

int get_max(std::vector<int> & vec) {//Could use const& instead, if it doesn't need to be modified
    int max = std::numeric_limits<int>::min();
    for(int & val : vec) {if(max < val) max = val;
    return max;
}
int get_max(std::array<int, 20> & arr) {//Could use const& instead
    int max = std::numeric_limits<int>::min();
    for(int & val : arr) {if(max < val) max = val;
    return max;
}

如果您希望这适用于任何std::array或任何std::vector,您可以像这样模板化它们:

template<typename T>
T get_max(std::vector<T> const& vec) {
    if(vec.size() == 0) throw std::runtime_error("Vector is empty!");
    T const* max = &vec[0];
    for(T const& val : vec) if(*max < val) max = &val;
    return *max;
}
template<typename T, size_t N>
T get_max(std::array<T, N> const& arr) {
    static_assert(N > 0, "Array is empty!");
    T * max = &arr[0];
    for(T & val : arr) if(*max < val) max = &val;
    return *max;
}

您的代码现在应如下所示以补偿:

void y(std::vector<int> & arr) //Can be const& if you don't need to modify it.
{}
void x(Node * tree, int n)
{
     std::vector<int> arr(n); //Will initialize n elements to all be 0.
     y(arr);
}

这个答案是为了说明在将VLA作为函数参数传递时,如何在C++中使用VLA。

在 c99 中,语法允许您将数组的大小作为参数传递给函数,并使用函数参数声明 VLA 的大小:

void y (int n, int (*arr)[n])
{}
void x (int n)
{
    int arr[n];
    y(n, &arr);
}

C++使用"函数名称重整"作为一种技术,将函数接受的参数类型编码到函数名称中,以支持函数重载。但是,在 GCC 中,由于 VLA 不是C++支持的功能,因此没有重整约定。有人可能会说这是一个 G++ 错误(或对 VLA 扩展的不完整支持(,但它就是这样。若要模拟按引用传递,请接受衰减的指针作为参数,并将其强制转换为对 VLA 的引用。

void y(int n, int *x)
{
    int (&arr)[n] = reinterpret_cast<int (&)[n]>(*x);
}
void x(int n)
{
    int arr[n];
    y(n, arr);
}

我已经验证了这适用于 GCC 4.8。

Xirema已经提到了如何使用std::vector/std::array解决此问题。

我不知道你的确切情况,所以只会描述另一种选择,尽管事实上,std::vector/std::array是最好的。

指针选项

在这里,你们相信,yarrn论点是一致的。并手动处理arr尺寸。

void y(int * arr, const int n) {}
void x(Node * tree, int n) {
     int arr[n];
     y(arr, n);
}

模板选项

这将起作用,它将在每个新N值上实例化 2 个模板。

template <size_t N>
void y(int (&arr)[N]) {}
template <size_t N>
void x(Node * tree) {
     int arr[N];
     y<N>(arr);
}