我正在實作一個 lambda 作為變數。在 C 20 中,它是這樣作業的:
auto lambda = []<typename T>() -> const T& {
...
};
現在我想將這種 lambda 函式存盤為結構的成員變數:
struct A {
??? m_lambda;
A(??? lambda) : m_lambda(lambda) {}
};
有沒有辦法做到這一點?
uj5u.com熱心網友回復:
您存盤任何模板化 lambda 的方式與存盤普通 lambda 的方式相同:
constexpr auto lambda = []<typename T>() {};
struct Foo{
decltype(lambda) m_lambda;
Foo():m_lambda(lambda){}
};
這是有效的,因為它operator()實際上是模板化的,而不是自動生成的 lambda 型別。
如果您不依賴行內對 lambda 的任何呼叫(出于性能考慮),則可以將其存盤起來以std::function<Ret(Args)>獲取正確的簽名。
std::function如果之前無法定義 lambda,這也是唯一的*選項,Foo這似乎是您的建構式的情況。
struct A {
std::function<void()> m_lambda;
// Not a lambda per se.
A(std::function<void()> lambda) : m_lambda(std::move(lambda)) {}
};
上面的內容并不是一個 lambda,因為在大多數情況下,將 lambda 作為引數并沒有真正意義,因為每個引數都有不同的型別,使得引數實際上是多余的。
*一個人總是可以制作A一個班級模板并使用CTAD進行扣除,但不確定你是否想這樣做。
uj5u.com熱心網友回復:
在 c 20 中,您可以執行以下操作:
struct Foo
{
decltype([] <class T> () {/* ... */ }) m_lambda {};
};
話雖如此,將 lambda 存盤為資料成員沒有任何意義。Lambda 不能更改,因此方法是簡單的首選替代方法。
uj5u.com熱心網友回復:
由于您的 lambda 是模板化的,因此您需要將 lambda 直接包含在您的物件中。
幸運的是,在 C 20(和 C 17)中很容易做到:
auto lambda = []<typename T>() -> const T& {
// ...
};
template<typename L> // <-- L is the lambda type
struct A {
L m_lambda;
A(L lambda) : m_lambda(lambda) {}
void foo() {
// Can call using many types using the template
int const& a = m_lambda.template operator()<int>();
float const& b = m_lambda.template operator()<float>();
}
};
int main() {
auto my_a = A{lambda}; // construct using the lambda and CTAD
my_a.foo();
}
相反,如果您A只需要呼叫模板的一個版本,則可以將 lambda 包裝在另一個 lambda 中:
struct A {
std::function<int const&()> m_lambda;
A(auto const& lambda) : m_lambda{
[lambda]{ return lambda.template operator()<int>(); }
} {}
void foo() {
// Can call and get a int const reference back
int const& a = m_lambda();
}
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/513847.html
標籤:C c 20
