![](/img/trans.png)
[英]error: no matching function for call to […] note: template argument deduction/substitution failed
[英]“template argument deduction/substitution failed” error with function object with parameter pack
我正在尝试制作一个函数,该函数需要可变数量的任何类型的参数,但是即使我所做的简单示例也遇到了错误
#include <iostream>
#include <functional>
template<class... Ts>
void callFunction(const std::function<void(Ts...)>& function, Ts... parameters)
{
function(parameters...);
}
void myFunc(const std::string& output)
{
std::cout << output << std::endl;
}
int main()
{
callFunction<const std::string&>(&myFunc, "Hello world");
return 0;
}
prog.cpp: In function ‘int main()’:
prog.cpp:17:57: error: no matching function for call to ‘callFunction(void (*)(const string&), const char [12])’
callFunction<const std::string&>(&myFunc, "Hello world");
^
prog.cpp:5:6: note: candidate: template<class ... Ts> void callFunction(const std::function<void(Ts ...)>&, Ts ...)
void callFunction(const std::function<void(Ts...)>& function, Ts... parameters)
^~~~~~~~~~~~
prog.cpp:5:6: note: template argument deduction/substitution failed:
prog.cpp:17:57: note: mismatched types ‘const std::function<void(Ts ...)>’ and ‘void (*)(const string&) {aka void (*)(const std::__cxx11::basic_string<char>&)}’
callFunction<const std::string&>(&myFunc, "Hello world");
一个简单的建议:以可推断的类型名而不是std::function
接收可调用对象
我的意思是(还添加了完美的转发功能)
template <typename F, typename ... Ts>
void callFunction(F const & func, Ts && ... pars)
{ func(std::forward<Ts>(pars)...); }
并且,显然,在不进行任何说明的情况下调用它
callFunction(&myFunc, "Hello world");
这是避免将callable转换为std::function
的额外优势。
无论如何,我在您的代码中看到两个问题:
1)如果您收到的函数作为std::function
接收相同类型的参数列表的ot参数类型列表(在这种情况下为可变列表,但对这个问题并不重要),则必须确保两个列表中的类型完全匹配。
这不是您的情况,因为该函数接收std::string const &
并且您将一个字符串文字"Hello world"
作为一个参数传递给它作为参数,而char const [12]
是另一种类型。
当推导类型时,这会导致编译错误,因为编译器无法在两种类型之间进行选择。
您可以解决接收两种类型的列表
template <typename ... Ts1, typename Ts2>
void callFunction (std::function<void(Ts1...)> const & function,
Ts2 && ... parameters)
{ function(std::forward<Ts2>(parameters)...); }
但是现在我们有第二个问题
2)您传递了一个指针函数( &myFunc
),其中callFunction()
等待std::function
。
我们有一个鸡蛋问题,因为&myFunc
可以转换为std::function
但不是std::function
。
因此,编译器无法从&myFunc
推断类型的Ts...
列表,因为它不是std::function
,也无法将&myFunc
转换为std::function
因为它不知道Ts...
类型列表。
我看到您已经说明了Ts...
列表中的第一个类型,但还不够,因为Ts...
列表是一个可变的,因此编译器不知道Ts...
只有一个类型Ts...
清单。
解决此问题的简单方法是将函数作为简单的F
类型传递。
否则,如果您编写了带有两个模板类型列表的callFunction()
,则可以将std::function
传递给该函数
std::function<void(std::string const &)> f{&myFunc};
callFunction(f, "Hello world");
但我认为这不是令人满意的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.