在C++中返回数组引用的语法

Syntax for returning an array reference in C++

本文关键字:引用 语法 数组 返回 C++      更新时间:2023-10-16

我一直在学习C++中的数组概念,当我遇到这个问题时:在C++中返回数组

有人用这个声明回答:

int (&f(int (&arr)[3]))[3]

我似乎无法理解的是结尾括号后面的[3]。我从未见过这样的函数声明。我理解其余的语法,但我并不特别理解[3]是如何工作的,因为它在函数名之后。如果我忽略了一些简单的事情,我会提前道歉。我还试着查看了函数声明的规范,但没有发现任何可以链接到下标语法的相关内容。那么,这怎么可能呢?

函数将引用返回到大小为3int的数组,而函数后面的[3]部分实际上是要返回为参考的数组的大小。

这种晦涩的语法来自数组声明的奇怪语法,您可以这样做:

int arr[3]; //real but weird

如果有,语言会简单得多

int[3] arr; //hypothetical but better and simpler

因为大小3arr类型的部分,所以如果所有部分都显示在变量名称的左侧,这将更有意义,就像您编写时一样

unsigned int a;

你不写:

unsigned a int; //analogous to : int a [3];

因此,尽管该语言对unsigned int做了正确的事情,但对int[3]却做了一件非常奇怪的事情。

现在回到函数声明,如果函数声明为:,它会更好

int[3]& f(int[3]& arr); //hypothetical

只有当它的所有部分都在变量名称的左侧时。但由于它不能做到这一点(即语言要求在变量名后的最右边写下大小(,您最终会得到这个奇怪的签名:

int (&f(int (&arr)[3])[3]; //real

请注意,即使是参数也会变得奇怪。


但您可以使用typedef将其简化为:

typedef int array_type[3];
array_type& f(array_type& arr);

看起来好多了。现在只有typedef看起来很奇怪。

使用C++11,您可以编写更好的typedef:

using array_type = int[3];
array_type& f(array_type& arr);

与此接近(如果您将array_type视为int[3](:

int[3]& f(int[3]& arr); //hypothetical

希望能有所帮助。

好吧,阅读这篇关于C历史的文章,作者是Dennis M.Ritchie。

看起来这个语法是我们从B,到C,再到C++。。。

我相信,这种声明一些"基本类型"的变量的方式是这种奇怪语法的根源:

int a, *b, c[3];

所以a就是intb是指向int的指针,cint的数组。。。

如果这些*[3]是类型定义的一部分,而不是变量定义,那么我们需要3行来写:

int a;
int* b;
int[3] c;

SOC页面上有两个很好的资源来学习如何解析这样的构造:

  • 用于解析C声明的顺时针/螺旋规则
  • cdecl:C胡言乱语↔English,一个将C表达式翻译成可读英语的网站

cdecl有点失败,因为引用不是C的一部分,所以让我们尝试使用顺时针/螺旋规则来解析C声明。

int (&f(int (&arr)[3]))[3]
  1. arr->arr
  2. &arr->arr为参考
  3. (&arr)->arr是参考-围绕()并没有真正改变什么
  4. (&arr)[3]->arr引用大小为3的数组
  5. int (&arr)[3]->arr是对int类型的大小为3的数组的引用

下一篇:

  1. f->f
  2. f(int (&arr)[3])->f是取arr的函数,它是
  3. &f(int (&arr)[3])->f是取arr的函数。。。,和返回引用
  4. (&f(int (&arr)[3]))[3]->f是取arr的函数。。。,并返回对大小为3的数组的引用
  5. int (&f(int (&arr)[3]))[3]->f是取arr的函数,arr是对int类型的大小为3的数组的引用,返回对int类型大小为3数组的引用

当然,这个代码应该被替换为,至少对我来说,更容易阅读的版本:

using int3 = int[3];
int3& f(int3& arr);
int (&f (int (&arr)[3]) )[3]
{
    return arr;
}

我们从里面开始吧。(int (&arr)[3])部分表示函数将引用一个由3个元素组成的int数组作为参数。这与正在返回的arr相同。

现在,语法的其余部分说,函数应该返回一个对3 int数组的引用。f是函数的名称。int &f()意味着你返回一个对int的引用,但你需要返回一个固定大小的数组,因此你应该添加[3]。使用&f(...)周围的括号是因为在c++中,你把数组的大小写在变量名后面,而不是像Nawaz在回答中解释的那样写在类型名后面。如果省略这些括号,编译器将把f解释为引用数组,如int & f[3]中所示。