2013-06-23 1 views
7

C++에서 함수와 동일한 서명을 가진 펑터를 반환하는 함수를 만들 수 있습니까?함수와 동일한 서명을 가진 펑터를 반환하는 함수를 만드는 방법은 무엇입니까?

기본적으로 합법화하는 방법은 decltype(foo) foo();입니다.

또는 펑와

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

나는 모든 상태는 객체의 다음 상태로 펑터를 반환하는 함수입니다 상태 머신이을 사용하고 싶습니다

. 지금 열거를 사용하여 구현했습니다,하지만 난 더 나은 방법이있을 것 같은 느낌 : 또한

#include <iostream> 
using namespace std; 

enum functionenum{END,FOO,BAR,BAZ}; 

functionenum foo(){ 
    cout<<"FOO! > "; 
    string s; 
    cin>>s; 
    if(s=="end") return END; 
    if(s=="bar") return BAR; 
       return FOO; 
} 

functionenum bar(){ 
    cout<<"BAR! > "; 
    string s; 
    cin>>s; 
    if(s=="end") return END; 
    if(s=="baz") return BAZ; 
       return BAR; 
} 

functionenum baz(){ 
    cout<<"BAZ! > "; 
    string s; 
    cin>>s; 
    if(s=="end") return END; 
    if(s=="bar") return BAR; 
    if(s=="foo") return FOO; 
       return BAZ; 
} 

void state(){ 
    auto f=foo; 
    while(true){ 
     switch (f()){ 
     case FOO: f=foo; break; 
     case BAR: f=bar; break; 
     case BAZ: f=baz; break; 
     case END: return; 
     }; 
    }; 
} 

int main(){ 
    state(); 
} 

: 문구에 덜 투박한 방법은 질문이?

당신은 구조체의 기능을 포장하여 형 재귀를 깰 수
+0

왜 VHDL 대신 C++로 상태 머신 코드를 작성하고 있습니까? –

+3

왜냐하면 저는 수학적 추상화에 대해서 말하고 실제 기계에 대해서는 말하지 않기 때문입니다. –

+0

글쎄, 당신이 의미하는 바는 "반환"에 달려 있습니다. 펑터는 funtions와 같은 방식으로 동작하므로 컴파일러는 아무 것도 반환하기 전에 펑터의 값을 평가하여 재귀로 끝나게됩니다. –

답변

7

:

#include <string> 

struct state 
{ 
    typedef state (*state_func)(const std::string &); 
    state(state_func f): function(f){} //not explicit, for notational convenience 
    state operator()(const std::string&arg) const 
    { 
     return function(arg); 
    } 
private: 
    state_func function; 

}; 

state f(const std::string &); 
state g(const std::string &) 
{ 
    return &f; 
} 
state f(const std::string &) 
{ 
    return &g; 
} 

int main() 
{ 
    state s(&f); 
    s = s("hello"); 
    return 0; 
} 

UPDATE : Yakk에 의해 코멘트를 한 후에는 ('만드는 것이 더 일반적인')와 루크 덴톤 ("클래식 GOTW") I 아래에 더 일반적인 C++ 11 버전을 추가합니다. 이것은 GOTW 버전을 기반으로합니다.

/// Type that wraps functions that return functions with the same signature. 
template<typename... Arguments> 
struct SelfReturningFunction 
{ 
    typedef SelfReturningFunction (*FunctionPointer)(Arguments...); 
    SelfReturningFunction(FunctionPointer f): function(f){} 
    operator FunctionPointer() const 
    { 
     return function; 
    } 
private: 
    FunctionPointer function; 
}; 

// example usage 
#include <string> 

using state = SelfReturningFunction<const std::string&>; 

state f(const std::string &); 
state g(const std::string &) 
{ 
    return &f; 
} 
state f(const std::string &) 
{ 
    return &g; 
} 
state dead_end(const std::string &) 
{ 
    return &dead_end; 
} 

int main() 
{ 
    state s{&f}; 
    s = s("hello"); 
    return 0; 
} 
+0

이것은'operator()'에 의해 훨씬 향상 될 것입니다. – Yakk

+0

@ k크, 네 말이 맞아. 연산자를 추가했습니다. _And_ const를 추가해 주셔서 감사합니다. – dhavenith

+0

유혹을받을 수있는 유일한 다른 변경 사항은'std :: string'을'template' arg로 만드는 것입니다. 오,'operator()'에서 완벽한 포워딩. – Yakk