Der*_*our 6 c++ parameters lambda
我现在正在学习 C++,对 Lambda 函数的语法非常困惑
我想在单元顶部定义 lambda,例如
typedef const std::function<void (bool)> bitloop;
Run Code Online (Sandbox Code Playgroud)
或者
typedef void bitloop(bool bit, int idx);
Run Code Online (Sandbox Code Playgroud)
稍后,将 lambda 接受到类中的函数中,例如,在我的 Bits 类中,有一个 forEach 方法
void forEach(const bitloop loop){
for (int i = 0; i<=fCount-1;i++){
loop(this->isSet(i),i);
}
}
Run Code Online (Sandbox Code Playgroud)
然后最终能够稍后编写不同的循环函数,传递一个值和循环索引,以便我可以捕获本地范围内的变量,例如
bits.forEach([&](bool on, int i){
output("index" + to_string(count)); //count is locally declared variable
});
Run Code Online (Sandbox Code Playgroud)
如果我删除 &,它可以与第二种类型 def 一起正常工作,但是我无法捕获计数变量。
有人可以解释一下我的做法哪里出了问题,以及这是否是一种有效的方法?
小智 7
首先,您的第二个typedef实际上是正确的,但您第一个的签名typedef不正确。这就是我声明std::function 的方式:
// T1 : function object
typedef std::function<void(bool, int)> T1;
// T2 : pointer to function
typedef void (*T2)(bool, int);
Run Code Online (Sandbox Code Playgroud)
正如您已经观察到的,捕获局部变量的 lambda 函数当前不能用作函数参数T2(请参阅本页上的注释)。下面显示的代码突出显示了此问题并重现了编译器错误。
struct Bits
{
void forEach(const T2 &loop)
{
//...
}
};
int main(int argc, char** argv)
{
int i = 0; // local variable
auto function1 = [](bool, int){ /**/ };
auto function2 = [&i](bool, int){ /**/ };
Bits bits;
bits.forEach(function1); // OK
//// if you uncomment the next line, the compiler would generate the following error
//// [Error] no matching function for call to 'Bits::forEach(main(int, char**)::<lambda(bool, int)>)'
//bits.forEach(function2);
Run Code Online (Sandbox Code Playgroud)
然而,捕获局部变量的 lambda 函数可以完美地用作T1.
struct Bits
{
void forEach(const T1 &loop)
{
//...
}
};
int main(int argc, char** argv)
{
int i = 0; // local variable
Bits bits;
auto function1 = [](bool, int){ /**/ };
auto function2 = [&i](bool, int){ /**/ };
bits.forEach(function1); // OK
bits.forEach(function2); // OK
Run Code Online (Sandbox Code Playgroud)
其次,还有另一种方法可以使用 lambda 作为函数参数,而无需显式声明std::function或函数类型……没错,它涉及到函数模板的使用。
struct Bits
{
template<typename T3> void forEach(const T3 &loop)
{
//...
}
};
int main(int argc, char** argv)
{
int i = 0; // local variable
Bits bits;
auto function1 = [](bool, int){ /**/ };
auto function2 = [&i](bool, int){ /**/ };
std::function<void(bool, int)> function3 = = [&i](bool, int){ /**/ };
bits.forEach(function1); // OK
bits.forEach(function2); // OK
bits.forEach(function3); // OK
bits.forEach([&i](bool, int){ /**/ }); // OK
Run Code Online (Sandbox Code Playgroud)
而且你也是对的,这就是如何定义一个捕获所有局部变量的 lambda 函数。
int i = 0; // local variable
Bits bits;
bits.forEach([&](bool, int){ /**/ }); // OK
Run Code Online (Sandbox Code Playgroud)
有关其他 lambda 捕获选项,请参阅cppreference。