我的意思是:

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

  return 0;
}

当前回答

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

但是我们可以在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++ 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开始