从函数返回多维数组

发布于 2024-09-24 04:01:20 字数 341 浏览 0 评论 0 原文

如何返回存储在类的 private 字段中的多维数组?

class Myclass {
private:
   int myarray[5][5];
public:
   int **get_array();
};

// This does not work:
int **Myclass::get_array() {
    return myarray;
}

我收到以下错误:

无法将 int (*)[5][5] 转换为 int** 作为返回

How do I return a multidimensional array stored in a private field of my class?

class Myclass {
private:
   int myarray[5][5];
public:
   int **get_array();
};

// This does not work:
int **Myclass::get_array() {
    return myarray;
}

I get the following error:

cannot convert int (*)[5][5] to int** in return

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

千笙结 2024-10-01 04:01:20

二维数组不会衰减为指向整数的指针。它衰减为指向整数数组的指针 - 也就是说,只有第一个维度衰减为指针。该指针不指向 int 指针(该指针在递增时会增加指针的大小),而是指向 5 个整数的数组。

class Myclass {
private:
    int myarray[5][5];
public:
    typedef int (*pointer_to_arrays)[5]; //typedefs can make things more readable with such awkward types

    pointer_to_arrays get_array() {return myarray;}
};

int main()
{
    Myclass o;
    int (*a)[5] = o.get_array();
    //or
    Myclass::pointer_to_arrays b = o.get_array();
}

当每个子数组单独分配时(也就是说,你最初有一个指针数组),使用指向指针的指针(int**

int* p[5];
for (int i = 0; i != 5; ++i) {
    p[i] = new int[5];
}

这里我们有一个由五个指针组成的数组,每个指针都指向第一个item在一个单独的内存块中,总共6个不同的内存块。

在二维数组中,您将获得单个连续的内存块:

int arr[5][5]; //a single block of 5 * 5 * sizeof(int) bytes

您应该看到这些东西的内存布局完全不同,因此这些东西不能以相同的方式返回和传递。

A two-dimensional array does not decay to a pointer to pointer to ints. It decays to a pointer to arrays of ints - that is, only the first dimension decays to a pointer. The pointer does not point to int pointers, which when incremented advance by the size of a pointer, but to arrays of 5 integers.

class Myclass {
private:
    int myarray[5][5];
public:
    typedef int (*pointer_to_arrays)[5]; //typedefs can make things more readable with such awkward types

    pointer_to_arrays get_array() {return myarray;}
};

int main()
{
    Myclass o;
    int (*a)[5] = o.get_array();
    //or
    Myclass::pointer_to_arrays b = o.get_array();
}

A pointer to pointer (int**) is used when each subarray is allocated separately (that is, you originally have an array of pointers)

int* p[5];
for (int i = 0; i != 5; ++i) {
    p[i] = new int[5];
}

Here we have an array of five pointers, each pointing to the first item in a separate memory block, altogether 6 distinct memory blocks.

In a two-dimensional array you get a single contiguous block of memory:

int arr[5][5]; //a single block of 5 * 5 * sizeof(int) bytes

You should see that the memory layout of these things are completely different, and therefore these things cannot be returned and passed the same way.

幽蝶幻影 2024-10-01 04:01:20

您可以返回两种可能的类型来提供对内部数组的访问。旧的 C 风格将返回 int *[5],因为数组很容易衰减为指向第一个元素的指针,该元素的类型为 int[5]

int (*foo())[5] {
   static int array[5][5] = {};
   return array;
}

现在,您还可以返回对内部数组的正确引用,最简单的语法是通过 typedef:

typedef int (&array5x5)[5][5];
array5x5 foo() {
   static int array[5][5] = {};
   return array;
}

或者没有 typedef 会更麻烦一些:

int (&foo())[5][5] {
   static int array[5][5] = {};
   return array;
}

C++ 版本的优点是保留实际类型,这意味着数组的实际大小在调用方是已知的。

There are two possible types that you can return to provide access to your internal array. The old C style would be returning int *[5], as the array will easily decay into a pointer to the first element, which is of type int[5].

int (*foo())[5] {
   static int array[5][5] = {};
   return array;
}

Now, you can also return a proper reference to the internal array, the simplest syntax would be through a typedef:

typedef int (&array5x5)[5][5];
array5x5 foo() {
   static int array[5][5] = {};
   return array;
}

Or a little more cumbersome without the typedef:

int (&foo())[5][5] {
   static int array[5][5] = {};
   return array;
}

The advantage of the C++ version is that the actual type is maintained, and that means that the actual size of the array is known at the callers side.

佼人 2024-10-01 04:01:20

要返回指向数组成员数组的指针,所需的类型是 int (*)[5],而不是 int **

class Myclass {
private:
    int myarray[5][5];
public:
    int (*get_array())[5];
};

int (*Myclass::get_array())[5] {
    return myarray;
}

To return a pointer to your array of array member, the type needed is int (*)[5], not int **:

class Myclass {
private:
    int myarray[5][5];
public:
    int (*get_array())[5];
};

int (*Myclass::get_array())[5] {
    return myarray;
}
一页 2024-10-01 04:01:20

如何返回隐藏在私有字段中的多维数组?

如果它应该被隐藏,为什么你首先要归还它?

无论如何,您不能从函数返回数组,但可以返回指向第一个元素的指针。 5x5 整数数组的第一个元素是什么?当然,是 5 个整数的数组:

int (*get_grid())[5]
{
    return grid;
}

或者,您可以通过引用返回整个数组:

int (&get_grid())[5][5]
{
    return grid;
}

...欢迎来到 C 声明符语法地狱 ;-)

我可以建议 std::vector 吗? >boost::multi_array 代替?

How do I return a multidimensional array hidden in a private field?

If it's supposed to be hidden, why are you returning it in the first place?

Anyway, you cannot return arrays from functions, but you can return a pointer to the first element. What is the first element of a 5x5 array of ints? An array of 5 ints, of course:

int (*get_grid())[5]
{
    return grid;
}

Alternatively, you could return the entire array by reference:

int (&get_grid())[5][5]
{
    return grid;
}

...welcome to C declarator syntax hell ;-)

May I suggest std::vector<std::vector<int> > or boost::multi_array<int, 2> instead?

涫野音 2024-10-01 04:01:20

更简单的是 decltype(auto) (C++14 起)

decltype(auto) get_array() { return (myarray); } // Extra parents to return reference

然后 decltype (C++11 起) (成员应该在方法之前声明)

auto get_array() -> decltype((this->myarray)) { return myarray; }
// or
auto get_array() -> decltype(this->myarray)& { return myarray; }

然后 typedef 方式:

using int2D = int[5][5]; // since C++11
// or
typedef int int2D[5][5];

int2D& get_array() { return myarray; }

因为常规语法非常难看:

int (&get_array())[5][5] { return myarray; }

使用 std::array, 5> (C++11 起) 将具有更自然的语法。

Simpler would be decltype(auto) (since C++14)

decltype(auto) get_array() { return (myarray); } // Extra parents to return reference

then decltype (since C++11) (member should be declared before the method though)

auto get_array() -> decltype((this->myarray)) { return myarray; }
// or
auto get_array() -> decltype(this->myarray)& { return myarray; }

then typedef way:

using int2D = int[5][5]; // since C++11
// or
typedef int int2D[5][5];

int2D& get_array() { return myarray; }

as regular syntax is very ugly way:

int (&get_array())[5][5] { return myarray; }

Using std::array<std::array<int, 5>, 5> (since C++11) would have more natural syntax.

巷子口的你 2024-10-01 04:01:20

我设法使用自动类型推导使这个函数在 C++0x 中工作。但是,如果没有它,我就无法让它工作。 C++ 中对本机 C 数组的支持不是很好 - 它们的语法极其丑陋。您应该使用包装类。

template<typename T, int firstdim, int seconddim> class TwoDimensionalArray {
    T data[firstdim][seconddim];
public:
    T*& operator[](int index) {
        return data[index];
    }
    const T*& operator[](int index) const {
        return data[index];
    }
};
class Myclass {
public:
    typedef TwoDimensionalArray<int, 5, 5> arraytype;
private:
    arraytype myarray;
public:
    arraytype& get_array() {
        return myarray;
    }
};

int main(int argc, char **argv) {
    Myclass m;
    Myclass::arraytype& var = m.get_array();
    int& someint = var[0][0];
}

这段代码编译得很好。您可以在 Boost (boost::array) 中获取预先编写的包装类,以支持整个 shebang。

I managed to make this function work in C++0x using automatic type deduction. However, I can't make it work without that. Native C arrays are not supported very well in C++ - their syntax is exceedingly hideous. You should use a wrapper class.

template<typename T, int firstdim, int seconddim> class TwoDimensionalArray {
    T data[firstdim][seconddim];
public:
    T*& operator[](int index) {
        return data[index];
    }
    const T*& operator[](int index) const {
        return data[index];
    }
};
class Myclass {
public:
    typedef TwoDimensionalArray<int, 5, 5> arraytype;
private:
    arraytype myarray;
public:
    arraytype& get_array() {
        return myarray;
    }
};

int main(int argc, char **argv) {
    Myclass m;
    Myclass::arraytype& var = m.get_array();
    int& someint = var[0][0];
}

This code compiles just fine. You can get pre-written wrapper class inside Boost (boost::array) that supports the whole shebang.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文