Nav*_*K N 7 c++ compiler-construction nested function
我正在阅读相关问题,这个问题引导我提出这个问题.
请考虑以下代码
int main()
{
string SomeString();
}
Run Code Online (Sandbox Code Playgroud)
总而言之,编译器将其作为函数原型而不是字符串对象.现在考虑以下代码.
int main()
{
string Some()
{
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
编译器说这是无效的,因为我猜不允许嵌套函数定义.如果不允许,为什么允许嵌套函数原型?它没有给予任何优势而不是混淆(或者我在这里错过了一些有效点?).
我想出以下是有效的.
int main()
{
string SomeFun();
SomeFun();
return 0;
}
string SomeFun()
{
std::cout << "WOW this is unexpected" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这也令人困惑.我期待函数SomeFun()只在main中有一个范围.但是我错了.为什么编译器允许编译如上所述的代码?有没有像上面这样的代码有意义的实时情况?
有什么想法吗?
小智 7
正如旁注,C++ 03确实有一种定义局部函数的迂回方式.它需要滥用本地级功能:
int main()
{
struct Local
{
static string Some()
{
return "";
}
};
std::cout << Local::Some() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这是C的约定 - 就像很多 - C++已经采用了这种约定.
在C中的另一个函数内声明函数的能力是大多数程序员可能认为令人遗憾和不必要的决定.特别是现代的OOP设计,其功能定义比C中的要小.
如果您希望函数仅存在于另一个函数的范围内,则两个选项是boost :: lambda和C++ 1x lambda.
至于为什么要申报
void f() {
void g(); g();
}
Run Code Online (Sandbox Code Playgroud)
比这更好
void g();
void f() {
g();
}
Run Code Online (Sandbox Code Playgroud)
如果您将声明尽可能保持在本地,这通常很好,因此尽可能少地命名冲突结果.我说在本地声明一个函数(这种方式)是否真的很幸运是有争议的,因为我认为普通包括它的标题然后采用"通常"方式更好,这对于不知道这一点的人来说也不那么混乱.有时,处理阴影函数也很有用
void f() {
int g;
// oops, ::g is shadowed. But we can work around that
{
void g(); g();
}
}
Run Code Online (Sandbox Code Playgroud)
当然,在C++中我们可以g使用函数来调用函数its_namespace::g()- 但是在C的旧时代,这是不可能的,并且那个东西允许程序员仍然访问函数.还要注意,虽然在语法上它不相同,但从语义上讲,以下内容也会在本地范围内声明一个实际上针对不同范围的函数.
int main() {
using std::exit;
exit();
}
Run Code Online (Sandbox Code Playgroud)
作为旁注,有更多情况,例如声明的目标范围不是声明出现的范围.通常,您声明的实体成为声明出现的范围的成员.但情况并非总是如此.考虑例如朋友声明,在那里发生的事情
struct X { friend void f() { std::cout << "WoW"; } };
int main() { void f(); f(); } // works!
Run Code Online (Sandbox Code Playgroud)
即使函数声明(和定义!)f发生在范围内X,实体(函数本身)也成为封闭命名空间的成员.
| 归档时间: |
|
| 查看次数: |
3559 次 |
| 最近记录: |