[英]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.