如何阅读这个声明 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;
}
我从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;
}