2

从这里:https ://stackoverflow.com/a/3473454/499125

int ( &fillarr( int (&arr)[5] ) )[5] { // no decay; argument must be size 5
    return arr;
}

上面的定义可以强制编译器意识到它的参数的大小。这句话对我来说似乎很复杂。有人可以对此声明进行剖析或解释该声明是如何实现尺寸意识的吗?

这可以扩展为处理多个参数吗?

4

2 回答 2

8

这一切都归结为能够阅读声明。一个更简单的写完全相同的方法是:

typedef int int5[5]; // create a typedef
int5& fillarr( int5& ) {
}

至于阅读原始声明的确切方式,只需将其分成几部分:

int (&fillarr( int (&arr)[5] ))[ 5 ];
               ^^^^^^^^^^^^^           // A: reference to array of 5 int
^^^^^^                        ^^^^^^   // B: reference to array of 5 int
      ^^^^^^^^               ^         // C: function taking A and returning B
于 2012-08-20T16:15:56.217 回答
2

您可以将其理解为两部分,1)返回值和 2)参数类型:

int ( &fillarr() )[5] {
  static int arr[5];
  return arr;
}

我们可以看一下类型:int (&fillarr())[5]. 为了理解这一点,不幸的是,旧的 C 规则:“声明就像表达式中的用法”不适用于引用,所以让我们看一下类似的声明:

int (*fillarr())[5];

这是一个返回指针而不是对大小为 5 的数组的引用的函数。我如何计算?好吧,假设我们确实有一个函数f返回一个指向整数数组的指针,我们将如何访问第五个元素?让我们看看,我们首先要调用函数:f()。然后我们必须取消引用结果*f(),然后访问第五个元素(它不存在,但忽略它)(*f())[5],它是一个int. 这正是声明语法:

int x;
int (*f())[5];
x = (*f())[5];
//    ^^^-------- call f -> yields pointer to array of 5 ints
//   ^----------- dereferene the result of f -> yields array of 5 ints
//        ^^^---- access the fifth element

现在您只需将 替换*为 an ,&因为您在示例中返回了一个引用。

参数语法的工作方式类似。

于 2012-08-20T16:16:18.397 回答