Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何创建返回与函数具有相同签名的函子的函数? < C++ >是否可以创建函数,返回与函数相同的签名符?_C++_Recursion_C++11_Functor_State Machine - Fatal编程技术网

如何创建返回与函数具有相同签名的函子的函数? < C++ >是否可以创建函数,返回与函数相同的签名符?

如何创建返回与函数具有相同签名的函子的函数? < C++ >是否可以创建函数,返回与函数相同的签名符?,c++,recursion,c++11,functor,state-machine,C++,Recursion,C++11,Functor,State Machine,基本上,如何使decltype(foo)foo()合法化 或与函子一起使用:函数 我想将其用于状态机,其中每个状态都是一个函数,它将一个函子返回到对象的下一个状态。我现在已经使用enum实现了它,但我觉得一定有更好的方法: #include <iostream> using namespace std; enum functionenum{END,FOO,BAR,BAZ}; functionenum foo(){ cout<<"FOO! > ";

基本上,如何使
decltype(foo)foo()合法化

或与函子一起使用:
函数

我想将其用于状态机,其中每个状态都是一个函数,它将一个函子返回到对象的下一个状态。我现在已经使用enum实现了它,但我觉得一定有更好的方法:

#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();
}
#包括
使用名称空间std;
枚举函数枚举{END,FOO,BAR,BAZ};
functionenum foo(){
cout>s;
如果(s==“结束”)返回结束;
如果(s==“bar”)返回条;
返回FOO;
}
函数枚举条(){
cout>s;
如果(s==“结束”)返回结束;
如果(s==“baz”)返回baz;
返回杆;
}
functionenum baz(){
cout>s;
如果(s==“结束”)返回结束;
如果(s==“bar”)返回条;
如果(s==“foo”)返回foo;
返回BAZ;
}
无效状态(){
自动f=foo;
while(true){
开关(f()){
案例FOO:f=FOO;中断;
案例条:f=条;中断;
案例BAZ:f=BAZ;中断;
案例结束:返回;
};
};
}
int main(){
状态();
}

还有:是否有一种更简单的方式来表达这个问题?

您可以通过将函数包装到结构中来打破类型递归:

#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;
}
#包括
结构状态
{
类型定义状态(*state_func)(常量std::string&);
state(state_func f):函数(f){}//不显式,为了便于记法
状态运算符()(常量std::string和arg)常量
{
返回函数(arg);
}
私人:
状态函数;
};
状态f(const std::string&);
状态g(常量std::string&)
{
返回&f;
}
状态f(常数std::string&)
{
return&g;
}
int main()
{
州s&f;
s=s(“你好”);
返回0;
}
更新:在Yakk(“使其更通用”)和Luc Danton(“经典”)的评论之后,我在下面添加了一个更通用的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;
}
///包装返回具有相同签名的函数的函数的类型。
模板
结构自返回函数
{
typedef SelfReturningFunction(*FunctionPointer)(参数…);
SelfReturningFunction(函数指针f):函数(f){}
运算符FunctionPointer()常量
{
返回函数;
}
私人:
函数指针函数;
};
//示例用法
#包括
使用状态=自返回功能;
状态f(const std::string&);
状态g(常量std::string&)
{
返回&f;
}
状态f(常数std::string&)
{
return&g;
}
状态死端(const std::string&)
{
返回和死胡同;
}
int main()
{
州{&f};
s=s(“你好”);
返回0;
}

为什么你用C++来编写状态机代码而不是VHDL呢?因为我在谈论数学抽象,而不是关于一个实际的机器。在某种程度上,函子的行为类似于函数,因此编译器在返回任何东西之前仍将计算函子的值,因此最终将使用递归。我的意思是只返回函子而不计算它。(作为函数指针)因此您试图从
状态返回函数
f
?通过
操作符()
,这将有很大的改进。我可能尝试的唯一其他更改是将
std::string
设置为
模板
参数。哦,在
操作符()
中实现了完美的转发。是的,参数甚至应该是一个参数包,但我只想展示一个state函数有参数的示例。我有点担心进一步的泛化会分散我对要点的注意力(另外:我还是一名C++98程序员)。