我的意思是:

int main() 
{
  void a() 
  {
      // code
  }
  a();

  return 0;
}

当前回答

所有这些技巧只是看起来(或多或少)像局部函数,但它们并不是这样工作的。在局部函数中,你可以使用超函数的局部变量。这是一种半全球化。这些把戏都做不到。最接近的是c++0x中的lambda技巧,但它的闭包是在定义时间内绑定的,而不是使用时间。

其他回答

现代c++ -是的,有lambdas!

在c++的当前版本(c++ 11、c++ 14和c++ 17)中,你可以在函数中使用lambda形式的函数:

int main() {
    // This declares a lambda, which can be called just like a function
    auto print_message = [](std::string message) 
    { 
        std::cout << message << "\n"; 
    };

    // Prints "Hello!" 10 times
    for(int i = 0; i < 10; i++) {
        print_message("Hello!"); 
    }
}

Lambdas还可以通过**引用捕获来修改局部变量。通过引用捕获,lambda可以访问lambda作用域中声明的所有局部变量。可以正常修改和更改。

int main() {
    int i = 0;
    // Captures i by reference; increments it by one
    auto addOne = [&] () {
        i++; 
    };

    while(i < 10) {
        addOne(); //Add 1 to i
        std::cout << i << "\n";
    }
}

c++ 98和c++ 03 -不能直接使用,但是可以在局部类中使用静态函数

c++并不直接支持。

也就是说,你可以有局部类,它们可以有函数(非静态或静态),所以你可以在某种程度上得到这个,尽管它有点拼凑:

int main() // it's int, dammit!
{
  struct X { // struct's as good as class
    static void a()
    {
    }
  };

  X::a();

  return 0;
}

然而,我对这种做法表示怀疑。每个人都知道(好吧,现在你知道了,反正:))c++不支持局部函数,所以他们习惯了没有它们。然而,他们并不习惯这种拼凑。我在这段代码上花了不少时间,以确保它确实只允许本地函数。不好的。

不,这是不允许的。C和c++默认情况下都不支持这个特性,但是TonyK指出(在评论中)有GNU C编译器的扩展可以在C中支持这个行为。

正如其他人所提到的,您可以通过在gcc中使用gnu语言扩展来使用嵌套函数。如果您(或您的项目)坚持使用gcc工具链,那么您的代码将能够在gcc编译器针对的不同体系结构之间进行移植。

然而,如果存在可能的需求,您可能需要使用不同的工具链编译代码,那么我将远离此类扩展。


在使用嵌套函数时,我也要小心。它们是管理复杂但内聚的代码块结构的一个漂亮的解决方案(这些代码块并不用于外部/一般用途)。它们在控制名称空间污染方面也很有帮助(在啰嗦语言中,对于自然复杂/长类来说,这是一个非常实际的问题)。

但和其他事情一样,它们也可能被滥用。

遗憾的是,C/ c++不支持这样的特性作为标准。大多数pascal变体和Ada都可以(几乎所有基于algol的语言都可以)。JavaScript也是一样。像Scala这样的现代语言也是如此。像Erlang、Lisp或Python这样的古老语言也是如此。

不幸的是,就像C/ c++一样,Java(我的大部分生活都是用它来赚取的)没有。

我在这里提到Java是因为我看到一些海报建议使用类和类的方法来替代嵌套函数。这也是Java中典型的解决方法。

简单的回答:不。

这样做往往会在类层次结构中引入人为的、不必要的复杂性。在所有条件都相同的情况下,理想的情况是让一个类层次结构(及其包含的名称空间和作用域)尽可能简单地表示一个实际的域。

嵌套函数有助于处理“私有的”、函数内的复杂性。如果没有这些工具,就应该尽量避免将“私有”复杂性传播到类模型中。

在软件(以及任何工程学科)中,建模是一个权衡的问题。因此,在现实生活中,这些规则(或指导方针)会有合理的例外。不过,要小心行事。

所有这些技巧只是看起来(或多或少)像局部函数,但它们并不是这样工作的。在局部函数中,你可以使用超函数的局部变量。这是一种半全球化。这些把戏都做不到。最接近的是c++0x中的lambda技巧,但它的闭包是在定义时间内绑定的,而不是使用时间。

让我在这里发布一个我认为最干净的c++ 03解决方案

#define DECLARE_LAMBDA(NAME, RETURN_TYPE, FUNCTION) \
    struct { RETURN_TYPE operator () FUNCTION } NAME;

...

int main(){
  DECLARE_LAMBDA(demoLambda, void, (){ cout<<"I'm a lambda!"<<endl; });
  demoLambda();

  DECLARE_LAMBDA(plus, int, (int i, int j){
    return i+j;
  });
  cout << "plus(1,2)=" << plus(1,2) << endl;
  return 0;
}

(*)在c++世界中使用宏从来不被认为是干净的。