将C++重载的函数指针提升为函数对象
Promotion of C++ overloaded function pointer to a function object
一个C++11模板函数,它接受函数对象参数,例如:
template <typename F, typename T>
auto foo(F f, T x) -> decltype(f(x)) {
return f(x);
}
可以采用以下功能:
int succ(int i) { return i+1; }
将CCD_ 1应用于CCD_
foo(succ,9);
过载的功能不起作用,例如sin
失败:
foo(std::sin,0.5);
GCC(4.7)中的"无法推导模板参数F"。
(顺便说一句,提供sin<double>
只与复杂类型有关。)是的,我可以直接构造它:
template <typename T>
struct Sin {
T operator()(T x) { return std::sin(x); }
};
有一点:
foo(Sin<double>(),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);
}
Ideone上的实例。
取代后的foo
将是void foo(void f(int), int x)
,这与foo(void (*f)(int), int x)
相同。这提供了一个所谓的"调用上下文",允许编译器选择正确的重载。显然,只有当第一个模板参数是函数时,这才有效。为了绕过这个限制,并使其看起来更好(imho,至少),您可以提供一个简单的辅助函数:
template<class F>
auto get_overload(F f) -> decltype(f) { return f; }
实际上,您只能重载参数类型,但这不能排除让用户键入返回类型的需要,因为这会再次禁用调用上下文,因为需要推导类型。
由于您很可能(或者肯定)只想将其用于函数指针,因此可以将其更改为:
template<class F>
F* get_overload(F* f){ return f; }
它仍然完全一样。第一个版本不能只使用F
作为返回类型的唯一原因是,如果用foo
2调用F
,那么它就是void(int)
,并且标准不允许返回函数(是的,这是一种函数类型)。函数到函数指针的转换(void(int)
->void(*)(int)
)部分只发生在参数中。
由于任何原因@VJovic删除了他的答案,我只会在中编辑
实际上,您可以使用一个简单的lambda来代替get_overload
函数。它将在字符方面具有相同的长度,并且更加方便和清晰。它也将更加高效,因为不涉及(函数)指针,并且编译器完全能够内联调用。
foo([](int i){ return bar(i); }, 5);
- 如何使用单独文件中的派生类访问友元函数对象
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 有没有办法将重载的类函数绑定到函数对象?
- 将指针传递到成员的指针,从模板参数包到函数对象
- 如何在类模板的成员函数中正确调用函数对象?正在生成 Visual Studio 编译器错误 C2440
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- C++使用函数对象的线程,如何调用多个析构函数而不是构造函数?
- 如何通过接口将函子分配给函数对象
- 对std::函数对象的调用不匹配,该对象是指向成员函数的指针
- 指向std::invoke中成员函数对象的指针
- 如何成功地将函数对象(或lambda)传递给trackbar回调的第二个参数(void*)
- "std::function"的简单版本:函数对象的生存期?
- C++ 将函数对象作为左值和/或右值传递
- SFINAE 用于具有默认参数的函数对象
- 构造函数对象赋值是否泄漏内存
- 如何发送通过绑定到函数/方法创建的函数对象?
- std::for_each 与函数对象
- 将函数对象传递给 std::function
- 访问执行策略for_each函数对象中的迭代器
- 通过C++函数对象类访问参数