我正在尝试根据我作为参数传递给它的 lambda 的数量来专门化一个模板化函数。这是我想出的解决方案:
template<typename Function, bool>
struct helper;
template<typename Function>
struct helper<Function, false>
{
auto operator()(Function&& func)
{
std::cout << "Called 2 argument version.\n";
return func(1, 2);
}
};
template<typename Function>
struct helper<Function, true>
{
auto operator()(Function&& func)
{
std::cout << "Called 3 argument version.\n";
return func(1, 2, 3);
}
};
template<typename T>
struct B
{
T a;
const T someVal() const { return a; }
};
template<typename Function, typename T>
auto higherOrderFun(Function&& func, const T& a)
{
return helper<Function, std::is_invocable<Function, decltype(a.someVal()), decltype(a.someVal()), decltype(a.someVal())>::value>{}(std::forward<Function>(func));
}
int main()
{
B<int> b;
std::cout << higherOrderFun([](auto x, auto y) {return x+y; }, b) << "\n";
std::cout << higherOrderFun([](auto x, auto y, auto z) {return x + y+z; }, b) << "\n";
return 0;
}
有没有办法以更优雅的方式实现这一目标?我已经看过了:Arity of a generic lambda
但是,最新的解决方案(florestan's)将所有参数都转换为aribtrary_t
,因此必须将它们转换回每个 lambda 内部,我认为这并不理想。理想情况下,我希望直接higherOrderFun
使用 SFINAE 专门化模板化,但我使用辅助类来实现这一点。有没有更直接的方法?例如直接应用 SFINAEhigherOrderFun
而不依赖于一个helper
类?这样做的重点是不必更改higherOrderFun
为higherOrderFun2
and higherOrderFun3
,而是让编译器从 lambda 和给定参数 ( const T& a
) 中推断出正确的特化。
我应该提一下,我也不关心函数参数的类型——只关心它们的数量,所以如果可能的话,我会在我的示例中更改decltype(a.someVal())
为auto
(也许有一种方法可以规避显式定义类型? )。