我的意思是:

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

  return 0;
}

当前回答

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++最恼人的解析

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


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

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

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

现代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中支持这个行为。

局部类已经提到过,但是这里有一种方法可以让它们更像局部函数,使用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;
} };