错误“lambda不是从'std :: function'派生的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了错误“lambda不是从'std :: function'派生的相关的知识,希望对你有一定的参考价值。
我正在尝试将lambda传递给通过可变参数模板定义的std :: function <>,但似乎这对gcc不起作用。
有什么理由,为什么这段代码不适用于gcc 7.4.0但在Visual Studio 2017上正常工作?有没有什么方法可以让它在gcc上工作,而无需先将它手动转换为std :: function <>?
#include <functional>
template<class ...TParams>
int TestFunction(std::function<void(TParams...)> )
{
return 0;
}
void Test()
{
auto fce = [](int /*n*/, double /*d*/) {};
//This doesn't work with error no matching function for call to 'TestFunction<int, double>(Test()::<lambda(int, double)>&)'
TestFunction<int, double>(fce);
//but this works correctly
std::function<void(int, double)> fce2 = fce;
TestFunction<int, double>(fce2);
}
我收到以下错误:
main.cpp: In function 'void Test()':
main.cpp:116:31: error: no matching function for call to 'TestFunction<int, double>(Test()::<lambda(int, double)>&)'
TestFunction<int, double>(fce);
^
main.cpp:106:5: note: candidate: template<class ... TParams> int TestFunction(std::function<void(TParams ...)>)
int TestFunction(std::function<void(TParams...)> fceCallback)
^~~~~~~~~~~~
main.cpp:106:5: note: template argument deduction/substitution failed:
main.cpp:116:31: note: 'Test()::<lambda(int, double)>' is not derived from 'std::function<void(TParams ...)>'
TestFunction<int, double>(fce);
^
答案
尾随模板参数包总是留有进一步扣除的空间。指定前两个参数不会阻止您执行以下操作:
std::function<void(int, double, char)> fce3 ;
TestFunction<int, double>(fce3);
在这种情况下,包将包含int, double, char
,因为char是从函数参数推导出来的。现在,因为演绎没有结束,并且lambda不是std :: function,所以替换失败。
为了使这个工作,您需要让演绎过程知道它已经结束,现在需要一个实例化的函数,在它给出一个参数之前。一种方法是使用函数的地址,例如:
auto pfunc = TestFunction<int, double>;
pfunc(fce);
要么
(&TestFunction<int, double>)(fce);
获取函数模板的地址是可以发生模板参数推导的另一个上下文。在这种情况下,尾随包被推断为空,并且您获得指向您可能调用的函数的指针。
以上是关于错误“lambda不是从'std :: function'派生的的主要内容,如果未能解决你的问题,请参考以下文章