簡體   English   中英

如何在 C++17 模板參數中限制 lambda 簽名?

[英]How can I restrict lambda signatures in C++17 template arguments?

假設我有兩個函數接收不同的 lambda 類型作為參數:

template<typename F>
void func1(F&& lambda) {
    // lambda must be [](unsigned int) -> short
}

template<typename F>
void func2(F&& lambda) {
    // lambda must be [](const vector<string>&) -> void
}

如何在 C++17 中限制這些 lambda 簽名,以完全匹配我在每種情況下所需的內容?

C++20 之前:

template<typename F, typename = std::enable_if_t<
    std::is_invocable_v<F, unsigned int>
>>
void  func1( F &&lambda ) {
    // lambda must be [](unsigned int) -> short
}

C++20:

template<typename F>
requires std::is_invocable_v<F, unsigned int>
void  func1( F &&lambda ) {
    // lambda must be [](unsigned int) -> short
}

如果您還想驗證返回類型,請使用 std::is_invocable_r_v 。

[編輯]

...使用 std::is_invocable_r_v

template<typename F, typename = std::enable_if_t<
    std::is_invocable_r_v<short, F, unsigned int>
>>
void  func1( F &&lambda ) {
    // lambda must be [](unsigned int) -> short
}

立即想到的一種方法是利用std::function及其推導指南。 使用 CTAD,可以為某些類型的函子(其中的非泛型 lambda)自動推導出簽名。 它看起來像這樣

template<typename F>
auto func1(F&& lambda) 
  -> std::enable_if_t<std::is_same_v<decltype(std::function{std::forward<F>(lambda)}), std::function<short(unsigned)>>> {
    // lambda must be [](unsigned int) -> short
}

std::function{std::forward<F>(lambda)}是一個函數式轉換表達式,它試圖將參數轉換為std::function其模板參數被推導。 如果推導成功,我們可以獲得一個類型來與std::function<short(unsigned)> 有了這個,我們可以使用標准庫中常用的 SFINAE 實用程序來約束func1

但是請注意,這不會將函數模板僅限於lambdas ,CTAD 成功並匹配參數列表的任何函子都將被接受。

暫無
暫無

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

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