c++ - std::invoke - 完美的转发函子
问题描述
试图理解为什么以下示例无法编译:
#include <functional>
template <typename F>
void f1(F&& f)
{
std::forward<F>(f)("hi");
}
template <typename F>
void f2(F&& f)
{
std::invoke(f, "hi"); // works but can't perfect forward functor
}
template <typename F>
void f3(F&& f)
{
std::invoke<F>(f, "hi");
}
int main()
{
f1([](const char*) {}); // ok
f2([](const char*) {}); // ok
f3([](const char*) {}); // error
}
cppreference说了以下关于std::invoke
:
f
使用参数 args调用 Callable 对象。正如INVOKE(std::forward<F>(f), std::forward<Args>(args)...)
.std::is_invocable_v<F, Args...>
此重载仅在为真时才参与重载决议。
那么为什么f3
不等于f1
呢?
解决方案
std::invoke
本身就是一个函数。在您的情况下,它的第一个参数是右值引用,f
而是左值,因此会发生错误。
INVOKE(std::forward<F>(f), std::forward<Args>(args)...)
std::invoke
在正确选择和调用函数后执行。基本上,您的 lambda 函数按如下方式传递:
original lambda in main -> the parameter of f3 -> the parameter of std::invoke -> the parameter of INVOKE
所以std::forward
在INVOKE(std::forward<F>(f), std::forward<Args>(args)...)
最后一步使用了in,而中步需要转发lambda(的参数f3
-> 的参数std::invoke
)。我想这就是你的困惑所在。
推荐阅读
- cuda - 如何在 xavier agx 上更新到 cuda 10.2?
- python - 如何在python中仅使用日期时间的时间部分?
- powerbi - Change value of a single cell in Power BI
- html - 将随机数放入 iframe src URL
- arrays - 如何删除每个元素的第一个元素
- javascript - 使用元响应元标记后代码没有响应?
- reporting-services - SSRS中的POS收据/连续纸打印
- ruby-on-rails - 更新每个进程的列信息
- c# - 在服务器上创建带有附件的电子邮件供用户下载
- wpf - 如何使路径旋转到位?