我的意思是:
int main()
{
void a()
{
// code
}
a();
return 0;
}
我的意思是:
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开始