基于 lambda 参数重载函数模板
Overloading function template based on lambda arguments
我正在尝试创建一个函数,调用者可以在其中传递具有一组特定已知参数的 lambda(return 类型可以是调用者想要的任何类型)
假设可能的 lambda 签名是
- T(小部件*)
- T (Widget2*)
我已经尝试了一些东西,但我无法让它们工作
struct Widget2{
int count = 0;
};
class Widget {
public:
template<typename Fn, typename T = std::invoke_result_t<Fn, Widget*>>
T doIt(Fn&& fn)
{
return fn(_sibling);
}
template<typename Fn, typename T = std::invoke_result_t<Fn, Widget2*>>
T doIt(Fn&& fn)
{
return fn(_other);
}
private:
Widget* _sibling = nullptr;
Widget2* _other = nullptr;
};
我也试过这样做
template<typename Fn>
auto doIt(Fn&& fn)
{
if (std::is_invocable_v<Fn, Widget*>)
return fn(_sibling);
else if (std::is_invocable_v<Fn, Widget2*>)
return fn(_other);
}
编译器中的这段代码:https://wandbox.org/permlink/wMAuw5XXnc0zTjlk
我宁愿避免添加 doItWidget1、doItWidget2 等多个函数。
有没有一种方法可以根据传入 lambda 的参数重载函数?
您可以使用 enable_if
消除错误的重载
template<typename Fn, std::enable_if_t<std::is_invocable_v<Fn, Widget*>, int> = 0>
auto doIt(Fn&& fn)
{
return fn(_sibling);
}
template<typename Fn, std::enable_if_t<std::is_invocable_v<Fn, Widget2*>, int> = 0>
auto doIt(Fn&& fn)
{
return fn(_other);
}
请注意,您甚至不需要弄清楚 return 类型 T
,您只需使用 auto
即可。
这里是 demo。
我正在尝试创建一个函数,调用者可以在其中传递具有一组特定已知参数的 lambda(return 类型可以是调用者想要的任何类型) 假设可能的 lambda 签名是
- T(小部件*)
- T (Widget2*)
我已经尝试了一些东西,但我无法让它们工作
struct Widget2{
int count = 0;
};
class Widget {
public:
template<typename Fn, typename T = std::invoke_result_t<Fn, Widget*>>
T doIt(Fn&& fn)
{
return fn(_sibling);
}
template<typename Fn, typename T = std::invoke_result_t<Fn, Widget2*>>
T doIt(Fn&& fn)
{
return fn(_other);
}
private:
Widget* _sibling = nullptr;
Widget2* _other = nullptr;
};
我也试过这样做
template<typename Fn>
auto doIt(Fn&& fn)
{
if (std::is_invocable_v<Fn, Widget*>)
return fn(_sibling);
else if (std::is_invocable_v<Fn, Widget2*>)
return fn(_other);
}
编译器中的这段代码:https://wandbox.org/permlink/wMAuw5XXnc0zTjlk
我宁愿避免添加 doItWidget1、doItWidget2 等多个函数。
有没有一种方法可以根据传入 lambda 的参数重载函数?
您可以使用 enable_if
消除错误的重载
template<typename Fn, std::enable_if_t<std::is_invocable_v<Fn, Widget*>, int> = 0>
auto doIt(Fn&& fn)
{
return fn(_sibling);
}
template<typename Fn, std::enable_if_t<std::is_invocable_v<Fn, Widget2*>, int> = 0>
auto doIt(Fn&& fn)
{
return fn(_other);
}
请注意,您甚至不需要弄清楚 return 类型 T
,您只需使用 auto
即可。
这里是 demo。