是否可以在 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();
}
还有:有没有更简洁的方式来表达这个问题?
最佳答案
您可以通过将函数包装在结构中来打破类型递归:
#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;
}
更新:在 Yakk(“让它更通用”)和 Luc Danton(“经典 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;
}
关于c++ - 如何创建返回与函数具有相同签名的仿函数的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17260487/