我正在尝试理解下面的代码所引起的编译器错误。我有一个可变参数的模板函数,该函数接受具有指定类型的lambda,并且尝试调用该函数会导致由于不匹配而导致模板不被视为有效候选者。
#include <functional>
template<typename ... ResultTypes>
void executeWithResultHandler(std::function<void (ResultTypes...)> lambda)
{
}
int main(int argc, char **argv)
{
executeWithResultHandler<int>([] (int arg) {
});
return 0;
}
这将导致以下错误:
$ c++ -std=c++11 reduction.cpp
reduction.cpp:10:5: error: no matching function for call to 'executeWithResultHandler'
executeWithResultHandler<int>([] (int arg) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
reduction.cpp:4:6: note: candidate template ignored: could not match 'function<void (int, type-parameter-0-0...)>' against
'<lambda at reduction.cpp:10:35>'
void executeWithResultHandler(std::function<void (ResultTypes...)> lambda)
^
1 error generated.
如果我将声明更改为可变参数:
template<typename ResultType>
void executeWithResultHandler(std::function<void (ResultType)> lambda)
{
}
那么它适用于上面的玩具示例,但是对于真正的问题,我需要任意参数。有什么我想念的东西吗?
编辑:这被错误地标记为重复项,我相信-欺骗并不能回答我所问的问题。这个问题特别与此处的可变参数模板问题有关:请注意,当我将模板切换为非可变时,lambda会按预期正确地转换为std :: function类型。不管参数有多少,这都是正确的,只要不以可变方式处理即可。
但是,它并没有使用专门的可变参数版本,尽管工作的期望,参数包解压后是一组真实参数,并在模板参数列表中的函数调用网站的明确规范。
在您的情况下,可变参数模板的问题在于,编译器不知道int
您显式指定的对象是否是其完整列表ResultTypes...
,因此它将尝试从您提供给它的参数中推断出可选的剩余参数,这显然会失败。这是可变参数模板参数的常见陷阱,不仅限于lambda。
一个解决方案总是意味着您从编译器中取消了此选项,例如
template<typename ... ResultTypes>
void executeWithResultHandler_impl(std::function<void (ResultTypes...)> lambda)
{
}
template<typename ... ResultTypes, typename F>
void executeWithResultHandler(F&& lambda)
{
executeWithResultHandler_impl(std::function<void (ResultTypes...)>(lambda));
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句