我的意思是:

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

  return 0;
}

当前回答

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

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

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

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


从c++ 11开始

其他回答

在c++中,你不能在另一个自由函数中定义一个自由函数。

是的,你可以用它们做一些甚至c++ 20 Lambdas都不支持的事情。即,对自身和相关函数的纯递归调用。

例如,Collatz猜想是,某个简单的递归函数最终将对任何正整数N产生“1”。使用显式的局部结构体和函数,我可以编写一个单独的自包含函数来对任何“N”运行测试。

constexpr std::optional<int> testCollatzConjecture(int N) { 
    struct CollatzCallbacks {
        constexpr static int onEven(int n) {
            return recurse(n >> 1); // AKA "n/2"
        }
        constexpr static int onOdd(int n) {
            if(n==1) return 1;     // Break recursion. n==1 is only possible when n is odd.
            return recurse(3 * n + 1);
        }
        constexpr static int recurse(int n) {
            return (n%2) ? onOdd(n) : onEven(n); // (n%2) == 1 when n is odd                
        }
    };

    // Error check
    if(N < 0) return {};

    // Recursive call.
    return CollatzCallbacks::recurse(N);
}

注意一些c++20 lambdas在这里不能做的事情:

I didn't need std::function<> glue OR lambda captures ("[&]") just to enable my local recursive functions call themselves, or each other. I needed 3 plain-old-functions with names, and that's all I had to write. My code is more readable and (due to (1)) will also run much faster. I cleanly separate the recursive logic in "CollatzCallbacks" from the rest of "testCollatzConjecture". It all runs in an isolated sandbox. I was able to make everything "constexpr" and state-less, so it can all run at compile time for any constant value. AFAIK I'd need c++23 just to achieve the recursion part with state-less lambdas.

记住:Lambda函数实际上只是编译器生成的局部结构体,如“CollatzCallbacks”,只是它们没有命名,并且只有一个“operator()”成员函数。您总是可以直接编写更复杂的局部结构和函数,特别是在您确实需要它们的情况下。

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

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

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

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


从c++ 11开始

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


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

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

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

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;
}