我试图制作一个模板函数,可以通过任何类型和数量的参数传递一些其他函数,并将其绑定到std::function
。我成功地做到这一点:Variadic模板,类型演绎和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)
,但如何?
你为什么要转换为'的std :: function'呢? 'std :: function'是一个类型擦除类:它从它构造的类型信息中获取,并擦除大部分内容。类型推断采用它的参数,并推导出它的类型,并生成代码。你要求推断出什么类型的东西要删除。这就像制作一套盔甲来制造枪支射向佩戴者;类型删除是大多数意义上的类型演绎的*对立*。这很少是一个好主意。这是可能的,但C++没有理由让它变得容易*你有一个实际的用例吗? – Yakk
重载或可变参数列表如何?只有在少数情况下才有可能。尽管你可以使用诸如boost function_traits之类的东西。 – tahsmith
@Yakk,我试图编写一个“memoization”函数,就是说它会返回一个带有相同参数的可调用函数,并且它的参数的返回类型会调用原始函数,除了它会查找以前的计算值(存储在合适的地图中)。我会使用'std :: function'来存储原始函数。不知道这是否可能。 – Tarc