5

I'd like to have a class with member functions that return pointers to member functions.

That is, something like:

class Foo {
// typedef ????(Foo::* func)????
public:
   Func s1();
   Func s2();
   Func s3();
}

Func Foo::s1() {
  // do stuff
  return &Foo::s2;
}

Func Foo::s2() {
  // do stuff
  return &Foo::s3;
}

Func Foo::s3() {
  // do stuff
  return 0;
}

Basically, what I try to do is to implement a state machine, where each state nows the next state and returns it by means of a function pointer.

Note: I'm not interested in other ways of implementing a state machine. I really like to know if it can be implemented in a way that looks like the above.

Context: I got inspired by this talk: http://www.youtube.com/watch?v=HxaD_trXwRE and wondered if a similar pattern can be used in C++.

Bertjan Broeksema
  • 1,541
  • 17
  • 28
  • 2
    [`std::function`](http://en.cppreference.com/w/cpp/utility/functional/function) and [`std::bind`](http://en.cppreference.com/w/cpp/utility/functional/bind) are your friends. – Captain Obvlious Oct 25 '13 at 22:01
  • You'd need something like `using Func = Func(Foo::*)();` - which is not allowed. – Daniel Frey Oct 25 '13 at 22:06
  • 1
    You can do this with function objects, but not functions/member functions. – jrok Oct 25 '13 at 22:08
  • 1
    What you want is a type dependent on itself (A recursive type?), which is obviously not allowed. – Manu343726 Oct 25 '13 at 22:25
  • 2
    GotW on this: http://www.gotw.ca/gotw/057.htm – Sam Cristall Oct 25 '13 at 22:26
  • 1
    @SamCristall copy the last section here and we have a winner. – Dialecticus Oct 25 '13 at 22:42
  • This isn't even possible for non-member functions (where you can find quite some duplicates). The type had to be *pointer to a function returning a pointer to a function returning a pointer to a function returning...*. – dyp Oct 25 '13 at 22:43
  • Related: http://stackoverflow.com/q/793449/420683 and with the same `struct` workaround here: http://stackoverflow.com/q/19349061/420683 – dyp Oct 25 '13 at 22:45

1 Answers1

4

Blatently ripping off the solution at GotW and adapting it to member functions:

class Foo {
  public:
    struct FuncPtrRet;
    typedef FuncPtrRet(Foo::*FuncPtr)();
    struct FuncPtrRet {
        FuncPtrRet(FuncPtr pp) : p(pp) { }
        operator FuncPtr() { return p; }
        FuncPtr p;
    };
    FuncPtrRet s1() { return &Foo::s2; }
    FuncPtrRet s2() { return &Foo::s3; }
    FuncPtrRet s3() { return &Foo::s3; }
};

int main() {
    Foo test;
    Foo::FuncPtr state = test.s1();
    state = (test.*state)();
    state = (test.*state)();
    state = (test.*state)();
    state = (test.*state)();
    state = (test.*state)();
    return 0;
}

This seems to work on Clang 3.3. I don't think returning 0 is a good choice for an idle state (s3 here), but I might be wrong there. Having an idle state that returns itself seems more intuitive to me.

Sam Cristall
  • 4,328
  • 17
  • 29
  • Yes, this is pretty much it! Pretty cool although it shows a bit that functional programming in C++ is not really straightforward. With respect to returning 0, this allows you to do something like: for (FuncPtrRet state = test.s1(); state != 0; ) { state = (test.*state)(); } – Bertjan Broeksema Oct 26 '13 at 10:07
  • Functional programming in C++ looks a lot better without member function pointers. Member function pointer syntax is atrocious. – Sam Cristall Oct 26 '13 at 19:23