在C或C ++中是否可以在另一个内部创建一个函数?
如果C或C ++中有可能,有人可以告诉我吗?
void fun_a(); //int fun_b(); ... main(){ ... fun_a(); ... int fun_b(){ ... } ... }
或类似的东西,例如函数内的类?
谢谢你的回复,
哇,我很惊讶没有人说是的! 自由函数不能嵌套,但函数和类通常可以。
void fun_a(); //int fun_b(); ... main(){ ... fun_a(); ... struct { int operator()() { ... } } fun_b; int q = fun_b(); ... }
您可以为仿函数提供构造函数并将对本地变量的引用传递给本地变量。 否则,它可以访问其他本地类型和静态变量。 但是,本地类不能是模板的参数。
C ++不支持嵌套函数,但是你可以使用boost :: lambda之类的东西。
C – 是的,因为gcc 是一个扩展名 。
C ++ – 没有。
你不能在C ++中的另一个函数内创建一个函数。
但是,您可以创建一个本地类functor:
int foo() { class bar { public: int operator()() { return 42; } }; bar b; return b(); }
在C ++ 0x中,您可以创建一个lambda表达式:
int foo() { auto bar = []()->int{return 42;}; return bar(); }
不,但在C ++ 0x中你可以http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions ,可能还需要几年才能完全支持。 在撰写本文时,该标准尚未完成。
-编辑-
是
如果您可以使用MSVC 2010.我成功运行了下面的代码
void test() { []() { cout << "Hello function\n"; }(); auto fn = [](int x) -> int { cout << "Hello function (" << x << " :))\n"; return x+1; }; auto v = fn(2); fn(v); }
产量
Hello function Hello function (2 :)) Hello function (3 :))
(我在项目工作参数部分写了>> c:\dev\loc\uniqueName.txt
并复制粘贴了这个结果)
您正在寻找的术语是嵌套函数 。 标准C和C ++都不允许嵌套函数,但GNU C允许它作为扩展。 这是一篇关于这个主题的好的维基百科文章 。
Clang / Apple正在研究C中的’块’,匿名函数! 😀
^(void){printf(“hello world \ n”); }
这里的信息和规格 ,ars technica有一点
不,并且至少有一个原因会导致事情变得复杂化。 嵌套函数通常应该可以访问封闭范围。 这使得“堆栈”不再能够用堆栈数据结构来表示。 相反,需要一个完整的树。
考虑以下代码,它实际上是在KennyTM建议的gcc中编译的。
#include typedef double (*retdouble)(); retdouble wrapper(double a) { double square() { return a * a; } return square; } int use_stack_frame(double b) { return (int)b; } int main(int argc, char** argv) { retdouble square = wrapper(3); printf("expect 9 actual %f\n", square()); printf("expect 3 actual %d\n", use_stack_frame(3)); printf("expect 16 actual %f\n", wrapper(4)()); printf("expect 9 actual %f\n", square()); return 0; }
我已经放置了大多数人希望打印的东西,但事实上,这是打印出来的:
expect 9 actual 9.000000 expect 3 actual 3 expect 16 actual 16.000000 expect 9 actual 16.000000
请注意,最后一行调用“square”函数,但在wrapper(4)调用期间修改了它访问的“a”值。 这是因为没有为“包装器”的每次调用创建单独的“堆栈”帧。
请注意,这些嵌套函数在支持它们的其他语言中实际上很常见,如lisp和python(甚至是最新版本的Matlab)。 它们带来了一些非常强大的函数编程function,但它们排除了使用堆栈来保存局部范围帧。
void foo() { class local_to_foo { public: static void another_foo() { printf("whatevs"); } }; local_to_foo::another_foo(); }
或者是C ++ 0x中的lambda。
您可以在函数中嵌套本地类 ,在这种情况下,该类只能被该函数访问。 然后,您可以将嵌套函数编写为本地类的成员:
#include int f() { class G { public: int operator()() { return 1; } } g; return g(); } int main() { std::cout << f() << std::endl; }
但请记住,您无法将本地类中定义的函数传递给STL算法,例如sort()
。
int f() { class G { public: bool operator()(int i, int j) { return false; } } g; std::vector v; std::sort(v.begin(), v.end(), g); // Fails to compile }
你从gcc得到的错误是“test.cpp:18:错误:没有匹配函数来调用`sort(__ gnu_cxx :: __ normal_iterator >>,__ gn_cxx :: __ normal_iterator >>,f():: G&)'”
无法在函数中声明函数。 但是,您可以在命名空间内或C ++中的类中声明一个函数。
不是标准的C,但gcc
和clang
支持它们作为扩展。 请参阅gcc在线手册 。
虽然C和C ++都禁止嵌套函数,但是一些编译器仍然支持它们(例如,如果内存服务,gcc可以,至少使用正确的标志)。 嵌套仿函数虽然更便携。
遗憾的是,C / C ++中没有嵌套函数。
正如其他答案所提到的,标准C和C ++不允许您定义嵌套函数。 (有些编译器可能允许它作为扩展,但我不能说我已经看到它被使用了)。
您可以在函数内声明另一个函数,以便可以调用它,但该函数的定义必须存在于当前函数之外:
#include #include int main( int argc, char* argv[]) { int foo(int x); /* int bar(int x) { // this can't be done return x; } */ int a = 3; printf( "%d\n", foo(a)); return 0; } int foo( int x) { return x+1; }
没有显式“链接说明符”的函数声明具有extern
链接。 因此,虽然函数main()
中的名称foo
的声明限定为main()
,但它将链接到稍后在文件中定义的foo()
函数(或者在另一个文件中,如果定义了foo()
)。