簡體   English   中英

將 lambda 作為參數傳遞給具有任意數量參數的 std::function 參數的函數

[英]Passing lambda as an argument to a function with std::function parameter with an arbitrary number of parameters

考慮下一個代碼示例:

template <typename... TArgs>
void foo(std::function<void(TArgs...)> f) {
}

template <typename... TArgs>
class Class {
public:
    static void foo(std::function<void(TArgs...)> f) {
    }
};

為什么我可以這樣做:

int main() {
// Helper class call
    Class<int, int>::foo(
        [](int a, int b) {}
    );
}

但是我在這樣做時遇到編譯錯誤:

int main() {
// Function call
    foo<int, int>(
        [](int a, int b) {}
    );
}
<source>:16:5: error: no matching function for call to 'foo'
    foo<int, int>(
    ^~~~~~~~~~~~~

<source>:4:6: note: candidate template ignored: could not match
    'std::function<void (int, int, TArgs...)>' against 
    '(lambda at <source>:17:9)'

void foo(std::function<void(TArgs...)> f) {
     ^

我只是想有一種方便的方式來使用諸如foo之類的功能。

我試過這個:


std::function<void(int, int)> f = [](int a, int b) {
    };

    foo<int, int>(f); // ok

它奏效了。 這沒關系。 但我想知道是否有任何方法可以在函數調用中直接使用 lambda,而無需創建本地函數對象。

因為這個: Why is template parameter pack used in a function argument type as its template argument list not can be explicited specified

當您調用foo<int, int>([](int a, int b) {}); , 包TArgs仍然被推導以防需要擴展。 std::function<void(TArgs...)>無法使用 lambda 參數為TArgs...推導任何內容,因此它被推導為一個空包,這與給定的int, int沖突。

對於Class<int, int>::foo ,沒有模板參數推導,因為模板參數已經給出。

對此的解決方法是將其置於非推導上下文中:

template <typename... TArgs>
void foo(std::type_identity_t<std::function<void(TArgs...)>> f) {
}

或者根本不使用std::function

template <typename F>
void foo(F&& f) {
}

暫無
暫無

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

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