【发布时间】:2015-01-20 05:33:46
【问题描述】:
有没有办法重写curry 模板类定义使main 接受curry<addtogether> 而不是当前的curry<int,int,int,addtogether>?
#include<iostream>
int addtogether(int x,int y){
return(x+y);};
template<class T,class U,class V,T(*F)(U,V)>
class curry{
private:
const U y;
public:
curry(U x):y(x){};
T operator()(V v){return(F(y,v));};
};
int main(){
{using namespace std;
cout<<curry<int,int,int,addtogether>(1)(1);}
};
这应该是可行的,因为addtogether 在编译时是已知的。我只是没有看到很多带有函数指针的模板。大多数是int(*f)(int,int) 的形式,它的多态性不够。我正在寻找一个模板定义,它可以接受任何带有两个参数的函数指针。
谢谢!
编辑:如果我的要求确实是不可能的,我想到了以下解决方法:
#include<iostream>
class addtogether{
public:
typedef int v1;
typedef int v2;
typedef int v0;
int operator()(int x,int y){
return(x+y);};
};
template<class F>
class curry{
public:
typedef typename F::v2 v1;
typedef typename F::v0 v0;
const typename F::v1 y;
curry(const typename F::v1 x):y(x){};
v0 operator()(const v1 v){return(F()(y,v));};
};
int main(){
{using namespace std;
cout<<curry<addtogether>(1)(1);}
};
我什至可以考虑用类型列表替换类型占位符 v0 v1 v2。
无论如何我都想分享一些东西......
【问题讨论】:
-
不作为类(类型被推导的模板非类型参数相对经常被请求)。但是您可以改用函数模板,并将函数指针作为运行时参数传递(依靠编译器优化来删除该间接)或将其包装在 lambda 中。
-
我不敢相信这是不可能的!什么极端情况会阻止编译器在编译时推断函数指针的类型?
-
如果
operator()没有重载,你可以从operator()的签名中推断出vX的类型。此外,您没有必须推断这些类型 - 您只需要存储参数,然后将它们传递给某个函数(对象)。见第一个链接:How to make curry?
标签: c++ templates function-pointers currying