C ++ 11将`auto` Lambda更改为不同的Lambda?
Posted
技术标签:
【中文标题】C ++ 11将`auto` Lambda更改为不同的Lambda?【英文标题】:C++11 Change `auto` Lambda to a different Lambda? 【发布时间】:2016-12-01 23:24:45 【问题描述】:假设我有以下包含 lambda 的变量:
auto a = [] return true; ;
我希望 a
稍后返回 false
。我可以按照这个思路做点什么吗?
a = [] return false; ;
这种语法给了我以下错误:
binary '=' : no operator found which takes a right-hand operand of type
'main::<lambda_a7185966f92d197a64e4878ceff8af4a>' (or there is no acceptable conversion)
IntelliSense: no operator "=" matches these operands
operand types are: lambda []bool ()->bool = lambda []bool ()->bool
有没有办法实现这样的目标?我想将 auto
变量更改为不同的 lambda。我是一个初学者,所以我可能缺少一些关于 auto
或 lambdas 的知识。谢谢。
【问题讨论】:
有bool b = true; auto a = [&b] return b; ; b = false;
解决方案,但这当然不能适用于所有情况。
【参考方案1】:
每个 lambda 表达式都会创建一个新的唯一类型,因此您的第一个 lambda 的类型与您的第二个 (example) 的类型不同。此外,lambda 的复制赋值运算符被定义为已删除 (example),因此您无法做到这一点。对于类似的效果,您可以将 a
设置为 std::function
对象,尽管这会降低您的性能
std::function<bool()> a = [] return true; ;
a = [] return false; ;
【讨论】:
【参考方案2】:可以使用一元 +
运算符将 Lambda 转换为函数指针,如下所示:
+[]return true;
只要捕获组为空且没有auto
参数。1
如果你这样做,你可以将不同的 lambdas 分配给同一个变量,只要 lambdas 都具有相同的签名。
在你的情况下,
auto a = +[]return true;;
a = +[]return false;;
Live example on Coliru
将按照您的预期进行编译和操作。2您可以像使用 lambda 一样使用函数指针,因为两者都将充当 functors。
1.在 C++14 中,您可以使用 auto
作为参数类型声明 lambda,例如 [](auto t)
。这些是generic lambdas,并有一个模板化的operator()
。由于函数指针不能表示模板函数,+
技巧不适用于泛型 lambda。
2。从技术上讲,您不需要分配的第二个 +
运算符。 lambda 将在赋值时转换为函数指针类型。不过,我喜欢这种一致性。
【讨论】:
C++正式进入Perl领域的那一刻! @jaggedSpire 我非常需要这个很多次,我认为唯一的解决方案是另一个function
对这个问题的回答。你是怎么知道的?我以前从未见过。
@JonathanMee 我实际上是从侧边栏中的相关链接中找到的,曾几何时:A positive lambda: +[]
- What sorcery is this?【参考方案3】:
每个 lambda 都有不同的类型,因此您无法更改它。您可以使用std::function 来保存任意可调用对象,可以随意更改。
std::function <bool ()> a = [] return true; ;
a = [] return false; ;
【讨论】:
我猜 Ryan 在发布同样的内容时击败了你。但是你少了一个分号。【参考方案4】:我们可以使用retrospective call 将 lambda 转换为 std::function:
template<typename T>
struct memfun_type
using type = void;
;
template<typename Ret, typename Class, typename... Args>
struct memfun_type<Ret(Class::*)(Args...) const>
using type = std::function<Ret(Args...)>;
;
template<typename F>
typename memfun_type<decltype(&F::operator())>::type
FFL(F const &func)
// Function from lambda !
return func;
之后我们就可以做(因为 'a' 现在是 std::function 类型):
auto a = FFL([] return false; );
a = FFL([] return true; );
【讨论】:
再解释一下就好了。【参考方案5】:由于C++17
,您可以通过Class template argument deduction 推导出std::function
模板参数。它甚至可以用于捕获 lambda:
int a = 24;
std::function f = [&a] (int p) return p + a; ;
f = [&a] (int p) return p - a; ;
f = [] (int p) return p; ;
这对更复杂的签名非常有用,对于推导的返回类型更有用。
【讨论】:
以上是关于C ++ 11将`auto` Lambda更改为不同的Lambda?的主要内容,如果未能解决你的问题,请参考以下文章
C++ auto_ptr 和 shared_ptr 从 VC++10 更改为 VC++12
将 Lambda 运行时从 Node 8.x 更改为 Node 12.x 后,从 AWS API Gateway 随机获得 502 Bad Gateway 响应