Search code examples
c++boostargument-passingfunction-signature

How to declare two functions taking each other's signature as argument?


Is it possible to emulate something like this:

typedef boost::function<void(A)> B;
typedef boost::function<void(B)> A;

The main goal is to be able to write code like this (in pseudo-c++):

void a_(B b) {
  // ...
  b(a_);
}
void b_(A a) {
  // ...
  f(boost::bind(a, b_));
}

f(boost::bind(a_, b_));

Solution

  • Not directly possible with typedefs; wherever a typedef is used, it is equivalent to the original type, so if you write

    typedef boost::function<void(A)> B;
    typedef boost::function<void(B)> A;
    

    then B would be equivalent to boost::function<void(A)>, which is equivalent to boost::function<void(boost::function<void(B)>)>, and so on, until you get

    boost::function<void(boost::function<void(boost::function<void(...)>)>)>
    

    , which is a type of infinite length.

    You can, however, define (at least) one of the two types as a struct or class:

    struct A;
    typedef boost::function<void(A)> B;
    struct A
    {
        B b;
        A(B b) : b(b) {}
    
        // optional:
        void operator() (A a) { b(a); }
    };
    

    You might need to add more constructors and/or a conversion operator to make the type behave completely "transparently", or you could just access the struct explicitly.