Hec*_*tor 29 c++ standards language-lawyer c++11
标准中哪些函数不允许返回函数?我知道它们在概念上是荒谬的,但在我看来,语法会允许它们.根据这个网页," noptr-declarator [是]任何有效的声明符 ",它将包含一个函数的声明符:
int f()();
Run Code Online (Sandbox Code Playgroud)
关于语法.
在我看来,[dcl.decl]中拼写的语法允许
int f(char)(double)
Run Code Online (Sandbox Code Playgroud)
这可以解释为功能 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
Run Code Online (Sandbox Code Playgroud)
粗略地说,在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.
Bar*_*rry 54
来自[dcl.fct],相当明确:
函数不应具有类型数组或函数的返回类型,尽管它们可能具有类型指针的返回类型或对此类事物的引用.虽然可以有函数指针数组,但是不应该有函数数组.
使用C++ 11,您可能只需要:
std::function<int()> f();
std::function<int(double)> f(char);
Run Code Online (Sandbox Code Playgroud)
关于C++语法存在一些混淆.int f(char)(double);
可以根据语法解析语句.这是一个解析树:
此外,基于[dcl.fct]/1,这样的解析甚至是有意义的:
在声明
T D
,其中D
具有形式
D1
(参数声明子句)CV-限定符-SEQ 选择
REF-限定符选择 异常规范选择 属性说明符-SEQ 选择
和所含的类型说明符-ID中的声明T D1
是" derived-说明符类型列表T
",该类型说明符-ID中D
是' 衍生的说明符类型列表的(功能参数声明子句)CV-限定符-SEQ 选择 REF-限定符选择返回T
’.
在这个例子T == int
中D == f(char)(double)
,D1 == f(char)
.的类型的说明符-ID中T D1
(int f(char)
)是"(字符)返回int的功能".所以derived-declarator-type-list是"(char)返回的函数".因此,类型f
将被读作"(char)返回函数(double)返回int的函数".
它最终无关紧要,因为这是一个明确禁止的声明者形式.但不是语法.
使用C++ 11(但不是以前版本的C++),您不仅可以返回类似C的函数指针,还可以返回C++ 闭包,特别是匿名函数.另请参见std :: function
标准不允许(从语义上讲,不是语法上 - 因此它不是语法问题 ;请参阅Barry对引文的回答)返回函数(并且还禁止sizeof
函数!)但允许返回函数指针.
顺便说一句,我不认为你可以返回整个功能.那是什么意思?你会如何实现?实际上,函数是一些代码块,它的名称(如数组)是指向函数机器代码开头的指针.
一个很好的技巧可能是在运行时构建(使用C++标准之外的机制)一个函数(然后处理它的函数指针).一些外部库可能允许的是:你可以使用JIT库(如asmjit,gccjit,LLVM ...),或简单地生成C++代码,然后编译并执行dlopen和dlsym进行它在POSIX系统等.
PS.您可能正确地理解C++ 11 语法(标准中的EBNF规则)不允许返回函数.这是一个用简单的英语表达的语义规则,它不允许(它不是任何语法规则).我的意思是单独的EBNF会允许:
// semantically wrong... but perhaps not syntactically
typedef int sigfun_T(std::string);
sigfun_T foobar(int);
Run Code Online (Sandbox Code Playgroud)
并且出于语义原因(不是因为EBNF规则),编译器正确地拒绝上述代码.实际上,符号表对C++编译器很重要(它不是语法或上下文语法).
关于C++的可悲事实是(由于遗留原因)它的语法(单独)非常模糊.因此,C++ 11难以阅读(对于人类而言),难以编写(对于开发人员而言),难以解析(对于编译器而言),....
using namespace std;
auto hello()
{
char name[] = "asdf";
return [&]() -> void
{
printf("%s\n", name);
};
}
int main()
{
hello()();
auto r = hello();
r();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
20167 次 |
最近记录: |