C++11 将 `auto` Lambda 更改为不同的 Lambda?
C++11 Change `auto` Lambda to a different Lambda?
假设我有以下包含 lambda 的变量:
auto a = [] { return true; };
我希望稍后 a
到 return 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 的知识。谢谢。
每个 lambda 表达式都会创建一个新的唯一类型,因此您的第一个 lambda 的类型与您的第二个 (example). Additionally the copy-assignment operator of a lambda is defined as deleted (example) 的类型不同,因此您无法做到这一点。为了达到类似的效果,您可以让 a
成为一个 std::function
对象,尽管它会花费您一些性能
std::function<bool()> a = [] { return true; };
a = [] { return false; };
可以使用一元 +
运算符将 Lambda 转换为函数指针,如下所示:
+[]{return true;}
只要捕获组为空且没有 auto
个参数。1
如果这样做,您可以将不同的 lambda 分配给同一个变量,只要这些 lambda 都具有相同的签名。
在你的情况下,
auto a = +[]{return true;};
a = +[]{return false;};
将按您的预期进行编译和操作。2 您可以像使用 lambda 一样使用函数指针,因为两者都将作为 functors.
1.在 C++14 中,您可以使用 auto
作为参数类型声明 lambda,例如 [](auto t){}
。这些是 generic lambdas,并且有一个模板 operator()
。由于函数指针不能表示模板化函数,因此 +
技巧不适用于通用 lambda。
2。从技术上讲,您不需要在作业中使用第二个 +
运算符。 lambda 将在赋值时转换为函数指针类型。不过,我喜欢这种一致性。
每个 lambda 都有不同的类型,因此您无法更改它。您可以使用 std::function 来保存任意可调用对象,可以随意更改。
std::function <bool ()> a = [] { return true; };
a = [] { return false; };
我们可以使用 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; });
由于 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; };
这对于更复杂的签名以及推导的 return 类型更方便。
假设我有以下包含 lambda 的变量:
auto a = [] { return true; };
我希望稍后 a
到 return 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 的知识。谢谢。
每个 lambda 表达式都会创建一个新的唯一类型,因此您的第一个 lambda 的类型与您的第二个 (example). Additionally the copy-assignment operator of a lambda is defined as deleted (example) 的类型不同,因此您无法做到这一点。为了达到类似的效果,您可以让 a
成为一个 std::function
对象,尽管它会花费您一些性能
std::function<bool()> a = [] { return true; };
a = [] { return false; };
可以使用一元 +
运算符将 Lambda 转换为函数指针,如下所示:
+[]{return true;}
只要捕获组为空且没有 auto
个参数。1
如果这样做,您可以将不同的 lambda 分配给同一个变量,只要这些 lambda 都具有相同的签名。
在你的情况下,
auto a = +[]{return true;};
a = +[]{return false;};
将按您的预期进行编译和操作。2 您可以像使用 lambda 一样使用函数指针,因为两者都将作为 functors.
1.在 C++14 中,您可以使用 auto
作为参数类型声明 lambda,例如 [](auto t){}
。这些是 generic lambdas,并且有一个模板 operator()
。由于函数指针不能表示模板化函数,因此 +
技巧不适用于通用 lambda。
2。从技术上讲,您不需要在作业中使用第二个 +
运算符。 lambda 将在赋值时转换为函数指针类型。不过,我喜欢这种一致性。
每个 lambda 都有不同的类型,因此您无法更改它。您可以使用 std::function 来保存任意可调用对象,可以随意更改。
std::function <bool ()> a = [] { return true; };
a = [] { return false; };
我们可以使用 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; });
由于 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; };
这对于更复杂的签名以及推导的 return 类型更方便。