C++ 推广C++;指向函数对象的重载函数指针

C++ 推广C++;指向函数对象的重载函数指针,c++,c++11,functor,C++,C++11,Functor,采用函数对象参数的C++11模板函数,例如: template <typename F, typename T> auto foo(F f, T x) -> decltype(f(x)) { return f(x); } 并将foo应用于succ,得到10的结果: foo(succ,9); 重载函数不起作用,例如,sin会失败: foo(std::sin,0.5); 在GCC(4.7)中,带有“无法推断模板参数F” (提供sin仅与复杂类型相关)是的,我可以立即构造它

采用函数对象参数的C++11模板函数,例如:

template <typename F, typename T>
auto foo(F f, T x) -> decltype(f(x)) {
  return f(x);
}
并将
foo
应用于
succ
,得到10的结果:

foo(succ,9);
重载函数不起作用,例如,sin会失败:

foo(std::sin,0.5);
在GCC(4.7)中,带有“无法推断模板参数F”

(提供
sin
仅与复杂类型相关)是的,我可以立即构造它:

template <typename T>
struct Sin {
  T operator()(T x) { return std::sin(x); }
};
模板
结构罪{
T运算符()(tx){return std::sin(x);}
};
有一点:

foo(Sin<double>(),0.5);
foo(Sin(),0.5);

我的问题是,有没有其他方法可以避免需要这样一个新的定义;仅可在调用站点
foo

上使用。对于函数指针,您只需让用户键入签名:

template<class F, class T>
void foo(F f, T x){
  f(x);
}

void bar(int){}
void bar(double){}

int main(){
  foo<void(int)>(bar, 5);
}
实际上,您只能重载参数类型,但这不能排除让用户类型为返回类型的需要,因为这会再次禁用调用上下文,因为需要推导类型

由于您很可能(或肯定)只希望函数指针使用此选项,因此可以将其更改为:

template<class F>
F* get_overload(F* f){ return f; }

static\u cast
是一种选择,虽然显然不是理想的选择。你说的
sin
不起作用是什么意思?它编译fine@VJovic你是什么意思我是什么意思?它不能编译。不过,你删除的答案确实如此。我不知道为什么。@user643722
static\u cast(sin)
选择了正确的重载。我希望这可以作为避免这种情况的一个教训。+1,需要注意的是,这是语言中唯一一个使用表达式的地方。另外,另一种解决方案是强制转换函数指针:
foo((void(*)(int))bar,5)
[这是一个静态强制转换],可以用作任何模板参数。
get\u重载的+1
。很好,非常好,还有一些比另一个
static\u cast
+1更友好,感谢你的亲切和添加了VJovic的答案。:-]
template<class F>
auto get_overload(F f) -> decltype(f) { return f; }
template<class F>
F* get_overload(F* f){ return f; }
foo([](int i){ return bar(i); }, 5);