【发布时间】:2014-07-13 03:16:47
【问题描述】:
我正在尝试了解我在下面的代码中遇到的编译器错误。我有一个接受 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)
{
}
那么它适用于上面的玩具示例,但对于真正的问题,我需要任意参数。 有什么我在这里遗漏的东西,或者另一种方法来完成这个吗?
编辑:我相信这被错误地标记为重复 - 骗子没有回答我要问的问题。这个问题与 variadic template 问题特别有关:请注意,当我将模板切换为非可变参数时,lambda 会按预期正确转换为 std::function 类型。无论参数有多少,只要不以可变参数方式处理,这都是正确的。
但是,它确实不适用于可变参数版本,尽管期望参数包被解包为一组实际参数,并且函数中模板参数列表的显式规范呼叫站点。
【问题讨论】:
-
lambda 不是
std::function对象。它们只是调用operator()的函数对象。因此,即使两个 lambda 具有相同的参数类型和返回类型,它们也有两种不同的类型。在此处查看我的相关问题:stackoverflow.com/questions/11628765/… -
在一个相关问题中,我有一个包装函数stackoverflow.com/a/21000981/683218,它可以使 std::function 对象在明确的情况下接受 lambda。
标签: c++ templates c++11 lambda variadic-templates