簡體   English   中英

在 C++17 中將 lambda 作為方法參數傳遞的最簡單方法

[英]Simplest way to pass a lambda as a method parameter in C++17

Google is showing me lots of SO posts on passing lambdas as arguments, but they all seem to be C++0x/C++11 based (eg Use a lambda as a parameter for a C++ function ) and I understand this is an area在最近的 C++ 版本中有所改進?

我想將一個非常簡單的委托return MyGlobals.GetX()作為方法變量傳遞——在我的例子中, MyGlobals是一個全局 object。 即在偽代碼

//stores and/or calls the lambda
myObject.SetXGetter({return MyGlobals.GetX()});

MyObject::SetXGetter(lambda?)
{
 this->mLambda = Lambda;
 cout << mLambda();
}

Older C++ versions made this quite messy having to use STL wrappers and temporary types, so in C++17 and above, how neatly can it be done... what would SetGetter look like and can it be called passing the lambda directly in?

(如果更新版本有不同的替代方案,請分享)

一個 function 在它自己的執行過程中只想調用一個傳遞的 lambda 或其他仿函數可以是一個 function 模板,推斷仿函數的類型

template <typename F>
void use_it(F&& func) {
    do_something_with(func());
}

在這里,您想要存儲稍后調用的函子,因此我們需要一個可以包裝各種函子的通用類型。 這就是std::function的用途。 假設返回類型為int

#include <functional>

class MyObject {
// ...
private:
    std::function<int()> mLambda;
};
void MyObject::SetXGetter(std::function<int()> func) {
    mLambda = std::move(func);
}

您的調用缺少 lambda 表達式所需的初始[ captures ] ,即使未捕獲任何內容:

myObject.SetXGetter([]{ return MyGlobals.GetX(); });

我知道這是一個在最近的 C++ 版本中有所改進的領域?

一般不會。 它已擴展到一些更復雜的情況,但簡單的情況與 C++11 幾乎相同。

在 C++17 中將 lambda 作為方法參數傳遞的最簡單方法

選項保持不變:

  • 您可以擁有一個模板並按原樣傳遞 lambda。
  • 或者您可以將 lambda 包裝在類型擦除包裝器中,例如std::function在這種情況下,您可以將其傳遞給非模板 ZC1C425268E68385D1AB5074C17A94F。
  • 或者如果 lambda 是非捕獲的,則可以將其轉換為 function 指針,該指針也可以傳遞給非模板。

哪一個最簡單可能因上下文和個人意見而異。 Function 包裝器在最廣泛的不同情況下工作方式相同,這是一個簡單的選擇。 Function 指針不涉及動態分配,在底層最容易理解。 模板不涉及任何類型的包裝或轉換,但它是一個模板。


 this->mLambda = Lambda;

鑒於您希望將可調用對象存儲為可修改成員,將其存儲為 lambda 不是一種選擇。 剩下的是 function 包裝器和 function 指針。 您仍然可以為 function 使用模板,但無論如何必須立即包裝或轉換 lambda,因此使用模板並沒有太多好處。

對於 C++20 及更高版本:

如果您不打算存儲傳遞的 function 可以執行以下操作

void use_it(auto func) {
    func();
}

您可能可以使用概念來進一步限制它,以便它除了至少是可調用的之外什么都沒有。

如果您想存儲參數,不幸的是,您仍然需要像其他答案所建議的那樣命名它,並且它必須能夠轉換為您指定的類型:

#include <functional>

class MyObject {
public:
    void SetXGetter(auto func) {
        mLambda = std::move(func);
    }

private:
    std::function<int()> mLambda;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM