【发布时间】:2019-07-06 10:34:54
【问题描述】:
有没有办法将std::is_invocable 与任意函数参数类型一起使用,例如:std::is_invocable<Function, auto>。这个想法是检查 Function 是否可以接受 1 个参数,而不管参数的类型如何。对于用例,请考虑两个 lambda:auto lambda1 = [](auto x) {...}、auto lambda2 = [](auto x, auto y) {...} 和一个更高阶的模板函数:
// specialize for 1 argument
template<typename Function, std::enable_if_t<(std::is_invocable<Function, auto>::value && !std::is_invocable<Function, auto, auto>::value)>, bool> = true>
void higherOrderFunc(Function&& func);
// specialize for 2 arguments
template<typename Function, std::enable_if_t<std::is_invocable<Function, auto, auto>::value, bool> = true>
void higherOrderFunc(Function&& func);
第一种情况下的!std::is_invocable<Function, auto, auto>::value 是为了防止重载函数出现歧义(也就是说,在这种情况下,首选的特化是在出现歧义时使用第二个参数)。
请注意,我知道在这种情况下不能像这样使用auto。我在问是否有办法实现这种行为(至少部分)。
【问题讨论】:
-
似乎没有任何方法可以检查这一点。为什么需要?
-
恐怕这是不可能的,因为它需要将所有类型都替换到函数模板中。您可以拥有仅对模板参数的某些组合有效的函数模板,并且这些条件可以任意复杂。请注意,只能调用函数,不能调用模板。这可能是什么用例?最后,你还是想使用一些具体的类型,那么,为什么不检查它们呢?
-
@Quimby 假设您有 100 种类型,手动为所有这些类型编写检查几乎不切实际。整个事情都与实现高阶函数有关。
-
不确定如何帮助您,可调用性可能取决于其参数。即使
template<typename T> foo(T,T)对这两个参数的所有类型都无效。并且对模板没有限制。函数本身可能被重载,所以 C++ 只能回答“如果我把这些具体参数放在那里,func(args...)是有效的表达式吗?”。类和函数模板都在实例化时使用具体类型进行检查,因此编译器可以开始将可用模板与这些具体类型进行匹配。你问的是相反的问题。 -
您能否举一个更具体的例子,在某物上使用高阶函数?不必是可编译的 C++。
标签: c++ c++17 sfinae type-deduction invocable