Small variadic template challenge: function composition

R

Rui Maciel

Does anyone know if it's possible to use (or abuse) variadic templates to
implement a way to concisely pull off function composition?

The following example can better describe what I mean:

<pseudo-code>
B AtoB(A)
{
//... do something
return B(something);
}

C BtoC(B)
{
//... do something
return C(something);
}

D CtoD(C)
{
//... do something
return D(something);
}


int main(void)
{
A a;

D d = composition<AtoB, BtoC, CtoD>(a); // magic happens

return 0;
}
</pseudo-code>



Thanks in advance,
Rui Maciel
 
G

Gert-Jan de Vos

Does anyone know if it's possible to use (or abuse) variadic templates to

implement a way to concisely pull off function composition?



The following example can better describe what I mean:



<pseudo-code>

B AtoB(A)

{

//... do something

return B(something);

}



C BtoC(B)

{

//... do something

return C(something);

}



D CtoD(C)

{

//... do something

return D(something);

}





int main(void)

{

A a;



D d = composition<AtoB, BtoC, CtoD>(a); // magic happens



return 0;

}

</pseudo-code>


Thanks in advance,

Rui Maciel

How about this:

struct A {};
struct B {};
struct C {};
struct D {};

struct AtoB
{
typedef A argument_type;
typedef B result_type;

B operator()(A a) const
{
return B();
}
};

struct BtoC
{
typedef B argument_type;
typedef C result_type;

C operator()(B b) const
{
return C();
}
};

struct CtoD
{
typedef C argument_type;
typedef D result_type;

D operator()(C C) const
{
return D();
}
};

template <typename Fn1, typename ... Fns>
struct composition
{
typedef typename Fn1::argument_type argument_type;
typedef composition<Fns ...> Tail;
typedef typename Tail::result_type result_type;

result_type operator()(argument_type a) const
{
Fn1 fn1;
Tail tail;
return tail(fn1(a));
}
};

template <typename Fn>
struct composition<Fn>
{
typedef typename Fn::argument_type argument_type;
typedef typename Fn::result_type result_type;

result_type operator()(argument_type a) const
{
Fn fn;
return fn(a);
}
};

template <typename... Fns>
typename composition<Fns ...>::result_type
compose(typename composition<Fns ...>::argument_type a)
{
composition<Fns ...> fn;
return fn(a);
}

int main()
{
A a;
D d = compose<AtoB, BtoC, CtoD>(a);
}

Regards,

Gert-Jan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top