c++ - 从作为模板函数参数传递的 std::function 推断返回和参数类型?
问题描述
我一直在四处寻找一段时间,但找不到我正在寻找的答案 -这个问题可能最接近我的想法。
一句话:是否可以声明一个模板函数,它接受一个参数std::function
并为函数的返回类型和参数类型推导出模板参数?例子:
//this works to pass the std::function in
template<class T>
void doSomething(std::function<T> f) {
f();
}
//this is more what i am looking for - can R and P be deduced automatically - does not work!
template<class R, class P>
void doSomethingElse(std::function<R(P)> f) {
f();
}
这是因为函数签名或函数类型本身被认为是一回事,因此不能“分解”?我意识到有decltype
但std::result_of
无法想到我可以在这里如何使用它们。
另外一点,我如何使用可变参数模板扩展第二个示例以具有多个参数和推论?
解决方案
template<class R, class P>
void doSomethingElse(std::function<R(P)> f) {
f(P{});
}
会起作用,但只有当你将 a 传递std::function
给函数并且该函数有一个非 void 参数时它才起作用。不过,这是一种限制。您可以使用
template<class R, class... Args, class... Ts>
void doSomethingElse(std::function<R(Args...)> f, Ts&&... args) {
f(std::forward<Args>(args)...);
}
它将接受任何std::function
参数并调用它们,就像您在调用站点中所做的一样。这仍然是限制性的,因为调用站点要求您使用 a std::function
,因此您不能将任何可隐式转换为 a 的内容传递给它std::function
。
使用 C++17 和类模板参数推导(CTAD),这不再是一个问题。我们可以创建一个接受任何类型的重载,然后使用 CTAD 构造一个 std::function 来为我们填充类型。那看起来像
template<class Func, class... Args>
void doSomethingElse(Func&& f, Args&&... args) {
doSomethingElse(std::function{std::forward<Func>(f)}, std::forward<Args>(args)...);
}
template<class R, class... Args, class... Ts>
void doSomethingElse(std::function<R(Args...)> f, Ts&&... args) {
f(std::forward<Args>(args)...);
}
现在,任何不是 a 的std::function
都将转到void doSomethingElse(Func&& f, Args&&... args)
,转换为 astd::function
并传递给,void doSomethingElse(std::function<R(Args...)> f, Args&&... args)
以便您可以在其中使用返回类型和参数类型。
推荐阅读
- django - 在 django 中为同一个视图使用两个 url?
- linux - 使用 ssl 证书在 ubuntu 中的 apache 上发布时,无法从 .NET Core Web 应用程序访问 js/css 库
- typescript - 打字稿:从联合类型中排除未定义
- python - asyncio.run(和其他风格)无法从 Celery 中的异常中恢复
- jquery - 将所有选中元素的字体颜色更改为红色
- html - 如何将菜单拆分为具有不同自动宽度的两列?
- c# - 使用参数发布到 api
- html - 为什么我的 a 标签会改变图标的颜色?
- javascript - 在 SMART Board(交互式白板)浏览器上打开网页,拖放不起作用
- visual-studio-2019 - 如何在不调试 (CTRL+F5) 的情况下仅用一根手指而不是在 Visual Studio 2019 中使用两根手指启动?