C ++函数返回函数

问题描述 投票:31回答:6

标准中哪里禁止返回函数?我理解它们在概念上是荒谬的,但是在我看来语法允许它们。根据此网页,“ noptr-declarator [is] any valid declarator”将包含函数的声明符:

int f()();

关于语法。

在我看来,[dcl.decl]中阐明的语法允许

int f(char)(double)

可以解释为函数f需要一个char并返回具有与 int g(double)相同签名的函数。

1    declarator:
2       ptr-declarator
3       noptr-declarator parameters-and-qualifiers trailing-return-type
4    ptr-declarator:
5        noptr-declarator
6        ptr-operator ptr-declarator
7    noptr-declarator:
8        declarator-id attribute-specifier-seq opt
9        noptr-declarator parameters-and-qualifiers
10       noptr-declarator [ constant-expression opt ] attribute-specifier-seq opt
11       ( ptr-declarator )
12    parameters-and-qualifiers:
13       ( parameter-declaration-clause ) cv-qualifier-seqAfter

大致来说,1-> 2,2 = 4,4-> 6,4-> 6你应该有ptr-operator ptr-operator ptr-operator然后,对第一个声明符使用4-> 5,5 = 7,7-> 8;第二和第三个声明符使用4-> 5,5 = 7,7-> 9。

c++ c++11 standards language-lawyer
6个回答
55
投票

从[dcl.fct],非常明显:

函数不得具有数组或函数的返回类型],尽管它们可能具有以下返回类型:输入指针或对此类事物的引用。尽管可以有数组,但不应有函数数组指向函数的指针。

使用C ++ 11,您可能只想要:

std::function<int()> f();
std::function<int(double)> f(char);

关于C ++语法有些困惑。根据语法分析语句int f(char)(double); can

。这是一个解析树:

“

此外,基于[dcl.fct] / 1,这样的解析甚至是有意义的:

在声明T D中,其中D的格式为D1parameter-declaration-clause

cv-qualifier-seq optref-qualifier opt exception-specification opt attribute-specifier-seq opt并且声明T D1中包含的declarator-id的类型为“ derived-declarator-type-list T”,Ddeclarator-id的类型是“ declared-declarator-type-list函数的功能(parameter-declaration-clausecv-qualifier-seq < [选择ref-qualifier opt返回T”。在此示例中为T == intD == f(char)(double)D1 == f(char)T D1int f(char))中的

declarator-id

的类型是“(char)返回int的函数”。因此derived-declarator-type-list是“(字符)返回的函数”。因此,f的类型将被理解为“(char)返回函数(double)返回int的函数。”最终什么也没做,因为这是明确禁止的声明器形式。但不是语法。

7
投票
使用C++11(但不是C ++的早期版本),您不仅可以返回类似C的函数指针,还可以返回C ++ closures,尤其是使用anonymous functions。另请参见std::function

0
投票
在C ++中,没有太大区别。对于所有可调用的创建,仍然可以使用C样式的函数指针或新的有用的std::function对象。 C ++还添加了lambda expressions,它们是内联函数,在某种程度上类似于功能语言中的闭包。它允许您不要使所有传递的函数成为全局函数。

最后,返回函数指针或std::function似乎很荒谬,但实际上并非如此。例如,状态机模式(在大多数情况下)基于返回指向处理下一个状态或可调用的下一个状态对象的函数的指针。


0
投票
如果语法没有提供完成某项任务的方式,那么我认为对于任何给定的上下文无关语言,语义或标准的含义并不重要。

0
投票

0
投票
但是,缺点是功能开头是“自动”的东西,那是不可移动的,没有类型可以匹配它(即使lambda也可以匹配模板类型std :: function <>)但如果您愿意,宏可以为您做魔术(有时是诅咒)

#define def auto

© www.soinside.com 2019 - 2024. All rights reserved.