如何解决如何在C ++ 17模板参数中限制lambda签名?
假设我有两个函数接收不同的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签名,以完全符合每种情况下的需要?
解决方法
立即想到的一种方法是利用<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="dropdown-1"></select>
<select id="dropdown-2"></select>
及其推论指南。使用CTAD,可以自动推导某些类型的函子(其中包括非通用lambda)的签名。看起来像这样
std::function
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
进行比较的类型。有了这些,我们可以使用标准库中常用的SFINAE实用程序来约束std::function<short(unsigned)>
。
但是请记住,这不仅将函数模板限制在 lambdas 上,CTAD成功实现并匹配参数列表的任何函子都将被接受。
,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
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。