当前位置: 首页 > 知识库问答 >
问题:

接受λ的可变模板函数

杜英范
2023-03-14

我试图理解下面代码中的编译器错误。我有一个variadic模板函数,它接受具有指定类型的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模板问题有关:请注意,当我将模板切换为非variadic时,lambda会像预期的那样正确地转换为std::function类型。无论参数的数量如何,只要不是以不同的方式处理,这都是正确的。

共有1个答案

孟鹏海
2023-03-14

variadic模板的问题在于,编译器不知道您显式指定的int是否是resulttypes...的完整列表,因此它试图从您给出的参数中推导出可选的其余参数,但显然失败了。这是不同模板参数的一个常见缺陷,并不局限于lambdas。

解决方案总是意味着从编译器中删除此选项,例如。

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));
}
 类似资料:
  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 考虑下面的代码 在第三个例子中,我知道模板推导不能发生,这就是为什么要显式指定模板参数。但是为什么没有从到

  • 有了C++20和概念,我想知道是否可以写一个概念来检查一个类型是否有一个带有特定名称的函数,该函数接受任意数量的任意参数。 以下面的代码为例(使用GCC当前的概念TS语法):

  • 将接受数组的函数改变为可变参数函数。 给定一个函数,返回一个闭包,将所有输入收集到一个接受函数的数组中。 const collectInto = fn => (...args) => fn(args); const Pall = collectInto(Promise.all.bind(Promise)); let p1 = Promise.resolve(1); let p2 = Promis

  • 我对编程和C++相当陌生。我有一个函数,我想接受以模板化值作为参数的函数指针。我的意思是... 我有这个功能: 我试过的: 结果: .h:165:22:注意:已忽略候选模板:无法将“function ,allocator >&)”与“void(*)(bool,std::vectorstd::vectorstd::allocatorstd::tuple &)”void postgrescaller:

  • 下面是一个完整演示我所看到的问题的程序。 首先,我从一个使用其他类型的分组定义的对象开始,我开始使用std::tuple<>来管理分组。 我打算这些对象能够将类型分散在“包”中。我已经意识到无法“实例化”这种类型的元组(请参见std::tuple中的Void类型) 这些类型的“分组”结构在可变递归中经常使用,它们永远不会被创建/使用。只是为了对模板arg进行分组。 但是,我“希望”对象的签名由“用