Small variadic template challenge: function composition

Discussion in 'C++' started by Rui Maciel, Apr 13, 2013.

  1. Rui Maciel

    Rui Maciel Guest

    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
    Rui Maciel, Apr 13, 2013
    #1
    1. Advertising

  2. On Saturday, April 13, 2013 2:04:09 PM UTC+2, Rui Maciel wrote:
    > 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
    Gert-Jan de Vos, Apr 13, 2013
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Colin Walters
    Replies:
    2
    Views:
    522
    Ben Pfaff
    Feb 13, 2004
  2. Ross A. Finlayson
    Replies:
    19
    Views:
    598
    Keith Thompson
    Mar 10, 2005
  3. Replies:
    2
    Views:
    345
    Dave Thompson
    Feb 27, 2006
  4. Replies:
    5
    Views:
    363
  5. Qi
    Replies:
    1
    Views:
    393
Loading...

Share This Page