现在C ++中有lambdas,我无法声明本地函数似乎真的很傻......
e.g:
我可以在函数体中声明一个类型,甚至可以将其初始化为值表。但我无法创建一个与该数据类型一起使用的辅助函数 - 因为我无法在函数中声明函数,并且我不能在函数外部引用该数据类型,因为它仅在该范围内可用。
有时候将数据类型拉出函数非常简单,并在那里定义我的数据类型和辅助函数(本地文件范围) - 但有时候它并不是真正合理的解决方案 - 例如使用引用局部范围变量(或者这个)的内联lambda初始化表时。
是否已经定义了对本地函数的支持是否已经定义,或者为什么编译器编写者难以实现它们,因此它们不是标准的一部分?
答案 0 :(得分:24)
没有本地函数,但如果没有闭包,它们就没那么有用,也就是访问局部变量。在任何情况下,您都可以使用lambda模拟一个本地函数。
而不是:
void foo(int x)
{
struct S
{
//...
};
int Twice(int n, S *s) //Not allowed
{
return 2*n;
}
S s;
int x = Twice(3, &s);
//...
}
执行:
void foo()
{
struct S
{
//...
};
auto Twice = [](int x, S *s) -> int //Cool!
{
return 2*x;
}; //Twice is actually a variable, so don't forget the ;
S s;
int x = Twice(3, &s);
//...
}
如果捕获集为空,([]
)它甚至可以转换为普通的指向函数的指针,就像真正的指针一样!
AFAIK,lambdas可以毫无困难地使用本地类型。但是,当然,该结构中的公共静态成员函数也可以正常工作。
作为另外一个与您的问题间接相关的注释,C ++ 11中允许的是使用本地类型(在C ++ 98中禁止)实例化模板:
void foo()
{
struct S {};
std::vector<S> vs; //error in C++98, ok in C++11
}
答案 1 :(得分:9)
C ++ 11中没有本地函数。
但是有lambdas。
您的本地类型可以具有成员函数!
答案 2 :(得分:3)
不,你不能这样做但是lambdas肯定比纯本地函数更有用,因为它们也可以选择捕获状态吗?它们既可以匿名使用,也可以分配给自动变量,并可以在任意多处使用。
以前,其他主要的解决方法(特别是在使用标准库算法时)是使用合适的operator()实现来定义本地functor结构。您还可以使用此方法捕获状态,但需要更多代码才能执行此操作。 Lambdas是一种非常简洁的方式来实现同样的目标。
答案 3 :(得分:1)
本地功能绝对不难实现,它们至少在1968年出现在Pascal中,甚至更早。它们在GCC中作为C扩展实现。
传递嵌套函数的地址有点复杂,它通常包括设置一段代码(trampoline),它首先设置静态链接/显示/用于访问局部变量的任何机制然后执行实际功能代码。 trampoline驻留在堆栈上,这意味着堆栈必须是可执行的,具有通常的安全隐患。
C ++委员会是否已考虑并拒绝嵌套函数是任何人的猜测,但我建议,虽然 难以实现,但嵌套函数的好处并不值得付出努力。< / p>
答案 4 :(得分:1)
它相当复杂,但您可以在本地结构类型中创建一个本地函数:
int quadruple(int x) {
struct Local {
static int twice(int val) { return val * 2; }
};
return Local::twice(Local::twice(x));
}
请注意,本地函数无法访问局部变量 - 您需要一个lambda。但是,它对本地重载很有用:
template <typename T>
T mod(T x, T y) {
struct Local {
static int local(int x, int y) { return x % y; }
static double local(double x, double y) { return std::fmod(x, y); }
};
return Local::local(x, y);
}