我的意思是:

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

  return 0;
}

当前回答

但是我们可以在main()中声明一个函数:

int main()
{
    void a();
}

虽然语法是正确的,但有时它会导致“最恼人的解析”:

#include <iostream>


struct U
{
    U() : val(0) {}
    U(int val) : val(val) {}

    int val;
};

struct V
{
    V(U a, U b)
    {
        std::cout << "V(" << a.val << ", " << b.val << ");\n";
    }
    ~V()
    {
        std::cout << "~V();\n";
    }
};

int main()
{
    int five = 5;
    V v(U(five), U());
}

=>无程序输出。

(编译后只有叮当声警告)。

又是c++最恼人的解析

其他回答

出于各种目的,c++通过lambdas:1来支持这一点

int main() {
    auto f = []() { return 42; };
    std::cout << "f() = " << f() << std::endl;
}

这里,f是一个lambda对象,充当main中的局部函数。可以指定捕获以允许函数访问本地对象。

在幕后,f是一个函数对象(即提供操作符()的类型的对象)。函数对象类型由编译器基于lambda创建。


从c++ 11开始

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

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


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

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

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

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

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

简单的回答:不。

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

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

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

No.

你想做什么?

处理:

int main(void)
{
  struct foo
  {
    void operator()() { int a = 1; }
  };

  foo b;
  b(); // call the operator()

}

但是我们可以在main()中声明一个函数:

int main()
{
    void a();
}

虽然语法是正确的,但有时它会导致“最恼人的解析”:

#include <iostream>


struct U
{
    U() : val(0) {}
    U(int val) : val(val) {}

    int val;
};

struct V
{
    V(U a, U b)
    {
        std::cout << "V(" << a.val << ", " << b.val << ");\n";
    }
    ~V()
    {
        std::cout << "~V();\n";
    }
};

int main()
{
    int five = 5;
    V v(U(five), U());
}

=>无程序输出。

(编译后只有叮当声警告)。

又是c++最恼人的解析

局部类已经提到过,但是这里有一种方法可以让它们更像局部函数,使用operator()重载和匿名类:

int main() {
    struct {
        unsigned int operator() (unsigned int val) const {
            return val<=1 ? 1 : val*(*this)(val-1);
        }
    } fac;

    std::cout << fac(5) << '\n';
}

我不建议使用这个,这只是一个有趣的技巧(可以做,但我不应该)。


2014年更新:

随着c++ 11的兴起,你现在可以有一些局部函数,其语法有点像JavaScript:

auto fac = [] (unsigned int val) {
    return val*42;
};

对于递归函数,不支持编译时类型演绎:

function<int(int)> factorial{ [&](int n)
{
        return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
} };