可变参数模板,类型推导和std :: function
我正在尝试制作一个模板函数,可以将任何类型和数量的参数传递给其他函数并将其绑定到 std :: function
。我设法做到了:
I'm trying to make a template function to which is possible to pass some other function with any type and number of parameters and bind it to a std::function
. I managed to do this:
#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);
并推断出类型,但是此行给出以下编译错误:
I would like to just call auto barp = func(foo);
and have the types deduced, but this line gives the following compilation errors:
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)
,但是
Why is it trying to match std::function<_Res(_ArgTypes ...)>
with int (*)(int)
? I feel I should get the compiler somehow to expand _Res(_ArgTypes ...)
to int(int)
, but how?
函数不是 std :: function
,它可以转换为一个。
但是,您可以推断出函数的参数,除非对重载有歧义。
A function is not an std::function
, it is convertible to one.
You can deduce the arguments of a function, however, barring ambiguity about overloads.
#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 与此类似,但显然不起作用:
What you want to do with the original std::function
is similar to this, which more obviously does not work:
template<typename T>
struct A
{
A(T);
};
template<typename T>
void func(A<T> a);
int main()
{
func(42);
}
42
不是 A
,但可以将其转换为一个。但是,将其转换为一个将需要知道 T
。
42
is not a A
, it can be converted to one, though. However, converting it to one would require T
to already be known.