[英]C++11 lambda as member variable?
可以將 lambda 定義為 class 成員嗎?
例如,是否可以使用 lambda 而不是 function object 來重寫下面的代碼示例?
struct Foo {
std::function<void()> bar;
};
我想知道的原因是因為以下 lambda 可以作為 arguments 傳遞:
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; });
}
我想如果 lambda 可以作為 function 參數傳遞,那么也許它們也可以存儲為成員變量。
經過更多的修補后,我發現這有效(但它有點毫無意義):
auto say_hello = [](){ std::cout << "Hello"; };
struct Foo {
typedef decltype(say_hello) Bar;
Bar bar;
Foo() : bar(say_hello) {}
};
A lambda just makes a function object, so, yes, you can initialize a function member with a lambda. 這是一個例子:
#include <functional>
#include <cmath>
struct Example {
Example() {
lambda = [](double x) { return int(std::round(x)); };
};
std::function<int(double)> lambda;
};
模板可以在沒有類型擦除的情況下實現,但就是這樣:
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; });
重復每個人已經公開的 arguments : []{}
不是類型,因此您不能像您嘗試的那樣將其用作例如模板參數。 使用decltype
也是不確定的,因為 lambda 表達式的每個實例都是具有唯一類型的單獨閉包 object 的表示法。 (例如上面f
的類型不是foo<decltype([] { return 42; })>
。)
有點晚了,但我在這里的任何地方都沒有看到這個答案。 如果 lambda 沒有捕獲 arguments,則可以將其隱式轉換為指向 function 的指針,並返回相同的 ZDBC11CAA5BDA999 類型。
例如,以下程序可以正常編譯並執行您期望的操作:
struct a {
int (*func)(int, int);
};
int main()
{
a var;
var.func = [](int a, int b) { return a+b; };
}
當然,lambdas 的主要優點之一是捕獲子句,一旦添加了它,那么這個技巧將根本不起作用。 如上所述,使用 std::function 或模板。
#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();
}
“如果 lambda 可以作為 function 參數傳遞,那么也可以作為成員變量傳遞”
第一個是肯定的,您可以使用模板參數推導或“自動”來這樣做。 第二個可能不是,因為您需要知道聲明點的類型,並且前兩個技巧都不能用於此。
一種可能有效但我不知道是否有效的方法是使用 decltype。
只要 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);
}
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()
{
Foo foo([](){ std::cout << "Hello"; });
foo.bar();
call_lambda(foo.bar);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.