如何阅读这个声明 int (*(*f2)(int n))[3];

how to read this declaration int (*(*f2)(int n))[3];

我从https://en.cppreference.com/w/cpp/language/scope那里得到了这个声明,但不知道如何解析这个声明,即使下面有评论。

我的问题是 如何解析声明语句(我将其视为指向函数协议的函数指针,如“int[3] foo(int n)”或“int foo(int n)[3]——它们在 C++ 中是非法的) ? 那么,如何构造一个可以赋值给这个函数指针的具体函数呢?谢谢。

const int n = 3;
int (*(*f2)(int n))[n]; // OK: the scope of the function parameter 'n'
                        // ends at the end of its function declarator
                        // in the array declarator, global n is in scope
// (this declares a pointer to function returning a pointer to an array of 3 int

它是一个指向函数的指针,该函数接受一个 int 并返回一个指向大小为三的 int 数组的指针。

所有评论都在说这里有 两个 n 标识符。 [n](在数组声明符中)使用的是 const int 3,而不是函数的参数(在函数声明符中)。

从中间开始,每个片段都包含在后续的要点中,如 ...:

  • f2是一个指针,(*f2).
  • 它是一个指向接受整数的函数的指针,...(int)
  • 它 returns 指向大小为三的 int 数组的指针,int (*...)[3]

你可以按照下面的完整程序为它构造一个具体的函数,输出第一个元素,42:

#include <iostream>

const int n = 3;
int (*(*f2)(int n))[n];

int (*g2(int))[n] {
    static int x[::n] = { 42 }; // Use outer n, not the parameter.
    return &x;                  //   since C++ has no VLAs. This
                                //   means parameter is not actually
                                //   needed in this test case, though
                                //   it may be in more complicated
                                //   tests.
}

int main() {
    f2 = &g2;                       // Assign concrete function to pointer.
    auto y = f2(3);                 // Call via pointer, get array.
    std::cout << *(y[0]) << '\n';   // Deref first element to get 42.
}

话虽如此,如果我的一位同事提交类似的东西进行代码审查,我会很好奇,至少没有大的评论解释它。尽管经验丰富的开发人员可能能够解决问题,但经验不足的开发人员可能会遇到麻烦。

而且,事实上,即使是经验丰富的开发人员 也不应该解决这个问题, 特别是考虑到我花了一些时间 分钟。

C++ 有一个非常有表现力的类型系统,它可以很容易地分段构建类似这样的东西,所以你不必为了解决它而经历偏头痛。对于这样的事情,我会使用 std::vector(或 std::array),除非有 令人信服的 情况,因为更多的基本类型会增加复杂性。

您可以为 pointer to an array of 3 int

创建类型
typedef int (*array_with_size_n)[n];

然后将其用作 return 类型

const int n = 3;
int (*(*f2)(int n))[n];
int arr[n];
array_with_size_n func(int n)
{
  return &arr;
}
int main()
{
   f2 = &func;
   return 0;
}