如何限制 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 签名,以准确匹配我在每种情况下的需要?
一种立即浮现在脑海中的方法是利用 std::function
及其推导指南。使用 CTAD,可以为某些类型的仿函数(其中 non-generic lambdas)自动推导签名。看起来像这样
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 成功并匹配参数列表的函子都将是已接受。
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
}
如果您还想验证 return 类型,请使用 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
}
假设我有两个函数接收不同的 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 签名,以准确匹配我在每种情况下的需要?
一种立即浮现在脑海中的方法是利用 std::function
及其推导指南。使用 CTAD,可以为某些类型的仿函数(其中 non-generic lambdas)自动推导签名。看起来像这样
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 成功并匹配参数列表的函子都将是已接受。
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
}
如果您还想验证 return 类型,请使用 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
}