Как создать функцию, которая возвращает функтор с той же сигнатурой, что и функция?

Можно ли в 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();
}

также: есть ли менее неуклюжий способ сформулировать вопрос?

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

ОБНОВЛЕНИЕ: после комментариев Якка («сделайте его более общим») и Люка Дантона («Классика» GOTW«) Я добавляю более общую версию 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;
}
7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]