我试图创建一个模板函数,可以通过任何类型和数量的参数传递一些其他函数,并将其绑定到std::function
。我设法做到了:
#include <iostream>
#include <functional>
int foo(int bar)
{
std::cout << bar << std::endl;
return bar;
}
template <typename Ret, typename... Args>
std::function<Ret (Args...)> func(std::function<Ret (Args...)> f)
{
return f;
}
int main()
{
//auto barp = func(foo); // compilation error
auto bar = func(std::function<void (int)>(foo));
bar (0); // prints 0
}
我想调用auto barp = func(foo);
并推断出类型,但这一行会产生以下编译错误:
error: no matching function for call to ‘func(void (&)(int))’
auto barp = func(foo);
^
note: candidate is:
note: template<class Ret, class ... Args> std::function<_Res(_ArgTypes ...)> func(std::function<_Res(_ArgTypes ...)>)
std::function<Ret (Args...)> func(std::function<Ret (Args...)> f)
^
note: template argument deduction/substitution failed:
note: mismatched types ‘std::function<_Res(_ArgTypes ...)>’ and ‘int (*)(int)’
auto barp = func(foo);
^
为什么要将std::function<_Res(_ArgTypes ...)>
与int (*)(int)
匹配?我觉得我应该以某种方式将编译器扩展到_Res(_ArgTypes ...)
到int(int)
,但是如何?
答案 0 :(得分:2)
一个函数不是std::function
,它可以转换为一个函数。
但是,你可以推断出一个函数的参数,除非有关重载的歧义。
#include <iostream>
#include <functional>
int foo(int bar)
{
std::cout << bar << std::endl;
return 0;
}
// Will cause error.
//int foo(double);
template <typename Ret, typename... Args>
std::function<Ret (Args...)> func(Ret f(Args...))
{
return f;
}
int main()
{
auto bar = func(foo);
bar (0); // prints 0
}
您想要对原始std::function
做什么与此相似,显然不起作用:
template<typename T>
struct A
{
A(T);
};
template<typename T>
void func(A<T> a);
int main()
{
func(42);
}
42
不是A
,但它可以转换为一个。但是,将其转换为一个则需要T
已知。