【发布时间】:2015-12-09 22:00:12
【问题描述】:
我正在尝试创建一个模板函数,可以向该函数传递具有任何类型和数量的参数的其他函数并将其绑定到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++ 没有理由让它简单你有实际用例吗? -
重载或变量参数列表怎么样?只有在少数情况下才有可能。不过你可以使用 boost function_traits 之类的东西。
-
@Yakk,我试图编写一个“memoization”函数,因为它将返回一个具有相同参数的可调用对象并返回其参数的类型,该参数将调用原始函数,除了它将查找以前的计算值(存储在合适的地图中)。我会使用
std::function来存储原始函数。不确定这是否可能。
标签: c++ c++11 variadic-templates std-function