dumb0
dumb0

Reputation: 337

Template class with function pointer parameter

Is there a way to rewrite the curry template class definition so main accepts curry<addtogether> instead of the current 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);}
};

This should be doable as addtogether is known at compile time. I've just not seen many templates with function pointers. The majority are of the form int(*f)(int,int) which is not polymorphic enough. I'm seeking a template definition that will accept any function pointer with two arguments.

Thanks!

Edit: If what I'm asking is indeed impossible, I thought of the following workaround:

#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);}
};

I could look into even replacing the type placeholders v0 v1 v2 by a list of types. Something I wanted to share anyway...

Upvotes: 2

Views: 1476

Answers (1)

Jonathan Wakely
Jonathan Wakely

Reputation: 171303

Is there a way to rewrite the curry template class definition so main accepts curry<addtogether> instead of the current curry<int,int,int,addtogether>?

No, because the non-type template parameter F depends on the earlier template parameters, so cannot be declared before them.

Do you really need the function pointer to be part of the type, rather than stored as a member variable of curry? Using a member variable would allow it to be deduced in a function template:

template<class T,class U,class V>
class curry{
private:
    T (*f)(U,V);
    const U y;
public:
    curry(T (*f)(U,V), U x): f(f), y(x){};
    T operator()(V v){return(f(y,v));};
};

template<class T,class U,class V>
curry<T, U, V>
make_curry(T (*f)(U,V), U u)
{
  return curry<T, U, V>(f, u);
}

Upvotes: 2

Related Questions