可以将lambda定义为类成员吗?
例如,是否可以使用lambda而不是函数对象重写下面的代码示例?
struct Foo {
std::function<void()> bar;
};
Run Code Online (Sandbox Code Playgroud)
我想知道的原因是因为以下lambda可以作为参数传递:
template<typename Lambda>
void call_lambda(Lambda lambda) // what is the exact type here?
{
lambda();
}
int test_foo() {
call_lambda([]() { std::cout << "lambda calling" << std::endl; });
}
Run Code Online (Sandbox Code Playgroud)
我想如果lambda可以作为函数参数传递,那么也许它们也可以存储为成员变量.
经过更多的修修补补后,我发现这有效(但这有点毫无意义):
auto say_hello = [](){ std::cout << "Hello"; };
struct Foo {
typedef decltype(say_hello) Bar;
Bar bar;
Foo() : bar(say_hello) {}
};
Run Code Online (Sandbox Code Playgroud)
wjl*_*wjl 38
lambda只是一个函数对象,所以,是的,你可以使用lambda初始化一个函数成员.这是一个例子:
#include <functional>
#include <cmath>
struct Example {
Example() {
lambda = [](double x) { return int(std::round(x)); };
};
std::function<int(double)> lambda;
};
Run Code Online (Sandbox Code Playgroud)
Luc*_*ton 19
模板可以在没有类型擦除的情况下实现,但就是这样:
template<typename T>
struct foo {
T t;
};
template<typename T>
foo<typename std::decay<T>::type>
make_foo(T&& t)
{
return { std::forward<T>(t) };
}
// ...
auto f = make_foo([] { return 42; });
Run Code Online (Sandbox Code Playgroud)
重复每个人都已经暴露的参数:[]{}不是一个类型,所以你不能将它用作例如你正在尝试的模板参数.使用decltype也是不确定的,因为lambda表达式的每个实例都是具有唯一类型的单独闭包对象的表示法.(例如f上面的类型不是 foo<decltype([] { return 42; })>.)
Sha*_*esh 13
有点晚了,但我没有在这里找到这个答案.如果lambda没有捕获参数,那么它可以隐式地转换为指向具有相同参数和返回类型的函数的指针.
例如,以下程序编译正常并执行您期望的操作:
struct a {
int (*func)(int, int);
};
int main()
{
a var;
var.func = [](int a, int b) { return a+b; };
}
Run Code Online (Sandbox Code Playgroud)
当然,lambdas的一个主要优点是capture子句,一旦你添加了它,那么这个技巧就行不通了.使用std :: function或模板,如上所述.
Ale*_* C. 11
#include <functional>
struct Foo {
std::function<void()> bar;
};
void hello(const std::string & name) {
std::cout << "Hello " << name << "!" << std::endl;
}
int test_foo() {
Foo f;
f.bar = std::bind(hello, "John");
// Alternatively:
f.bar = []() { hello("John"); };
f.bar();
}
Run Code Online (Sandbox Code Playgroud)
只要 lambda 是常数(没有闭包),你就可以这样做:
#include <iostream>
template<auto function>
struct Foo
{
decltype(function) bar = function;
};
void call_lambda(auto&& lambda)
{
lambda();
}
int main()
{
Foo<[](){ std::cout << "Hello"; }> foo;
foo.bar();
call_lambda(foo.bar);
}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/W5K1rexv3
或者我们可以应用推导指南使其适用于所有 lambda:
#include <iostream>
template<typename T>
struct Foo
{
T bar;
};
template<typename T>
Foo(T) -> Foo<std::decay_t<T>>;
void call_lambda(auto&& lambda)
{
lambda();
}
int main()
{
std::string hello = "Hello";
Foo foo([&](){ std::cout << hello; });
foo.bar();
call_lambda(foo.bar);
}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/cenrzTbz4
| 归档时间: |
|
| 查看次数: |
39181 次 |
| 最近记录: |