我的意思是:

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

  return 0;
}

当前回答

让我在这里发布一个我认为最干净的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++世界中使用宏从来不被认为是干净的。

其他回答

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

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


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

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

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

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

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

简单的回答:不。

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

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

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

从c++ 11开始,你可以使用合适的lambdas。更多细节请参见其他答案。


老答案:你可以,在某种程度上,但你必须欺骗和使用一个虚拟类:

void moo()
{
    class dummy
    {
    public:
         static void a() { printf("I'm in a!\n"); }
    };

    dummy::a();
    dummy::a();
}

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

c++中不能有局部函数。然而,c++ 11有lambdas。lambda基本上是像函数一样工作的变量。

A lambda has the type std::function (actually that's not quite true, but in most cases you can suppose it is). To use this type, you need to #include <functional>. std::function is a template, taking as template argument the return type and the argument types, with the syntax std::function<ReturnType(ArgumentTypes)>. For example, std::function<int(std::string, float)> is a lambda returning an int and taking two arguments, one std::string and one float. The most common one is std::function<void()>, which returns nothing and takes no arguments.

一旦声明了lambda,就像普通函数一样调用它,使用lambda(arguments)语法。

To define a lambda, use the syntax [captures](arguments){code} (there are other ways of doing it, but I won't mention them here). arguments is what arguments the lambda takes, and code is the code that should be run when the lambda is called. Usually you put [=] or [&] as captures. [=] means that you capture all variables in the scope in which the value is defined by value, which means that they will keep the value that they had when the lambda was declared. [&] means that you capture all variables in the scope by reference, which means that they will always have their current value, but if they are erased from memory the program will crash. Here are some examples:

#include <functional>
#include <iostream>

int main(){
    int x = 1;

    std::function<void()> lambda1 = [=](){
        std::cout << x << std::endl;
    };
    std::function<void()> lambda2 = [&](){
        std::cout << x << std::endl;
    };

    x = 2;
    lambda1();    //Prints 1 since that was the value of x when it was captured and x was captured by value with [=]
    lambda2();    //Prints 2 since that's the current value of x and x was captured by reference with [&]

    std::function<void()> lambda3 = [](){}, lambda4 = [](){};    //I prefer to initialize these since calling an uninitialized lambda is undefined behavior.
                                                                 //[](){} is the empty lambda.

    {
        int y = 3;    //y will be deleted from the memory at the end of this scope
        lambda3 = [=](){
            std::cout << y << endl;
        };
        lambda4 = [&](){
            std::cout << y << endl;
        };
    }

    lambda3();    //Prints 3, since that's the value y had when it was captured

    lambda4();    //Causes the program to crash, since y was captured by reference and y doesn't exist anymore.
                  //This is a bit like if you had a pointer to y which now points nowhere because y has been deleted from the memory.
                  //This is why you should be careful when capturing by reference.

    return 0;
}

You can also capture specific variables by specifying their names. Just specifying their name will capture them by value, specifying their name with a & before will capture them by reference. For example, [=, &foo] will capture all variables by value except foo which will be captured by reference, and [&, foo] will capture all variables by reference except foo which will be captured by value. You can also capture only specific variables, for example [&foo] will capture foo by reference and will capture no other variables. You can also capture no variables at all by using []. If you try to use a variable in a lambda that you didn't capture, it won't compile. Here is an example:

#include <functional>

int main(){
    int x = 4, y = 5;

    std::function<void(int)> myLambda = [y](int z){
        int xSquare = x * x;    //Compiler error because x wasn't captured
        int ySquare = y * y;    //OK because y was captured
        int zSquare = z * z;    //OK because z is an argument of the lambda
    };

    return 0;
}

您不能更改lambda中通过value捕获的变量的值(通过value捕获的变量在lambda中具有const类型)。为此,您需要通过引用捕获变量。下面是一个例子:

#include <functional>

int main(){
    int x = 3, y = 5;
    std::function<void()> myLambda = [x, &y](){
        x = 2;    //Compiler error because x is captured by value and so it's of type const int inside the lambda
        y = 2;    //OK because y is captured by reference
    };
    x = 2;    //This is of course OK because we're not inside the lambda
    return 0;
}

另外,调用未初始化的lambdas是未定义的行为,通常会导致程序崩溃。例如,永远不要这样做:

std::function<void()> lambda;
lambda();    //Undefined behavior because lambda is uninitialized

例子

下面是你想在你的问题中使用lambdas做的代码:

#include <functional>    //Don't forget this, otherwise you won't be able to use the std::function type

int main(){
    std::function<void()> a = [](){
        // code
    }
    a();
    return 0;
}

下面是一个更高级的lambda示例:

#include <functional>    //For std::function
#include <iostream>      //For std::cout

int main(){
    int x = 4;
    std::function<float(int)> divideByX = [x](int y){
        return (float)y / (float)x;    //x is a captured variable, y is an argument
    }
    std::cout << divideByX(3) << std::endl;    //Prints 0.75
    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++最恼人的解析