2013-10-25 3 views
4

Я хотел бы иметь класс с функциями-членами, которые возвращают указатели на функции-члены.Функции-члены, возвращающие указатели на функции-члены

То есть, что-то вроде:

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

В принципе, то, что я пытаюсь сделать, это осуществить государственную машину, где каждое состояние актуалистов следующего состояния и возвращает его с помощью указателя функции.

Примечание: Меня не интересуют другие способы реализации конечного автомата. Мне очень нравится знать, можно ли это реализовать так, как показано выше.

Контекст: Я получил вдохновение от этого разговора: http://www.youtube.com/watch?v=HxaD_trXwRE и задался вопросом, можно ли использовать аналогичный шаблон в C++.

+2

['std :: function'] (http://en.cppreference.com/w/cpp/utility/functional/function) и [' std :: bind'] (http: //en.cppreference. com/w/cpp/utility/functional/bind) являются вашими друзьями. –

+0

Вам понадобится что-то вроде 'using Func = Func (Foo :: *)();' - это недопустимо. –

+1

Вы можете сделать это с помощью объектов функций, но не функций/функций-членов. – jrok

ответ

3

Blatently срывая раствора при GotW и адаптации его к функциям-членам:

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

Это, кажется, работает на Clang 3.3. Я не думаю, что возвращение 0 - хороший выбор для состояния бездействия (s3 здесь), но я, возможно, ошибаюсь. Наличие бездействующего состояния, которое возвращает себя, кажется мне более интуитивным.

+0

Да, это в значительной степени это! Довольно круто, хотя это немного показывает, что функциональное программирование на C++ не является простым. Что касается возврата 0, это позволяет сделать что-то вроде: для (FuncPtrRet state = test.s1(); state! = 0;) { state = (test. * State)(); } –

+0

Функциональное программирование на C++ выглядит намного лучше без указателей функций-членов. Синтаксис указателя функции-члена является жестоким. –

Смежные вопросы