简体   繁体   English

返回函数指针的函数的 C 语法

[英]C syntax for functions returning function pointers

Consider the following typedefs :考虑以下类型定义:

typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);

f2 is a function that returns a function pointer. f2是一个返回函数指针的函数。 The same with f3 , but the type of the function, the pointer to which f3 returns, is f2 .f3相同,但函数的类型,即f3返回的指针,是f2 How can I define f3 without the typedefs?如何在没有 typedef 的情况下定义f3 I know typedefs are the cleaner and easier to understand way to define f3 .我知道 typedef 是定义f3的更清晰、更容易理解的方法。 However, my intention here is to understand C syntax better.但是,我在这里的目的是更好地理解 C 语法。

Start with your declaration for f1 : 从声明f1

int (*f1)(float);

You want f2 to be a pointer to a function returning f1 , so substitute f1 in the declaration above with the declaration for f2 : 你想f2是一个指针,返回一个函数f1 ,所以替代f1在以上声明的声明f2

int (*      f1     )(float);
            |
      +-----+-----+
      |           |
      v           v
int (*(*f2)(double))(float);

The declaration reads as 该声明为

        f2                   -- f2
       *f2                   -- is a pointer
      (*f2)(      )          -- to a function
      (*f2)(double)          --   taking a double parameter
     *(*f2)(double)          --   returning a pointer
    (*(*f2)(double))(     )  --   to a function
    (*(*f2)(double))(float)  --     taking a float parameter
int (*(*f2)(double))(float)  --     returning int

You repeat the process for f3 : 您重复f3的过程:

int (*(*    f2    )(double))(float);
            |
        +---+----+
        |        |
        v        v
int (*(*(*f3)(int))(double))(float);

which reads as 读为

          f3                           -- f3
         *f3                           -- is a pointer
        (*f3)(   )                     -- to a function
        (*f3)(int)                     --   taking an int parameter
       *(*f3)(int)                     --   returning a pointer
      (*(*f3)(int))(      )            --   to a function
      (*(*f3)(int))(double)            --     taking a double parameter
     *(*(*f3)(int))(double)            --     returning a pointer
    (*(*(*f3)(int))(double))(     )    --     to a function
    (*(*(*f3)(int))(double))(float)    --       taking a float parameter
int (*(*(*f3)(int))(double))(float);   --       returning int

In C++, the miracle of templates can make this a tad easier. 在C ++中,模板的奇迹可以使这一点变得更容易。

#include <type_traits>

std::add_pointer<
    std::add_pointer<
        std::add_pointer<
            int(float)
        >::type(double)
    >::type(int)
>::type wow;

The same as with the typedef, only you place your function definition in place of its name. 与typedef相同,只是您将函数定义放在其名称的位置。

Here's how f2 would look like: 这是f2样子:

typedef int (*(*f2)(double))(float);

You can do f3 as an exercise, since I'm assuming this is homework ;) 您可以将f3做为练习,因为我假设这是家庭作业;)

Just don't. 只是不要。 It can be done, but it will be very confusing. 可以做到,但是会非常混乱。 Typedef's are there to ease writing and reading this short of code. 使用Typedef可以简化编写和阅读这段简短代码的过程。

A function f that takes no arguments and returns a function pointer int (*)(float) would probably be something like (untested): 不带任何参数并返回函数指针int (*)(float)的函数f可能类似于(unested):

int (*f())(float);

Then for the rest you just need to keep adding parenthesis until it looks like lisp. 然后,对于其余部分,您只需要继续添加括号,直到看起来像lisp。

Learn the the right-left rule : 了解左右规则

The "right-left" rule is a completely regular rule for deciphering C declarations. “左右”规则是用于解密C声明的完全规则的规则。 It can also be useful in creating them. 在创建它们时也很有用。

Use std::function : 使用std::function

typedef std::function<int(float)> f1;
typedef std::function<f1(double)> f2;
typedef std::function<f2(int)>    f3;

or 要么

typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3;

Inspired by John Bode's answer, I want to present it in a graphical way.受约翰博德回答的启发,我想以图形方式呈现它。 Maybe it will help you to understand how the compiler would lex it into an AST:也许它会帮助您了解编译器如何将其词法转换为 AST:

函数中的函数返回值,递归

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM