如何将 std::function 的零个或多个参数用作 std::map 中的值

How to have zero or more arguments to a std::function used as value in a std::map?

本文关键字:std 参数 map 零个 function      更新时间:2023-10-16

我有一个引擎类,它有一个类型为std::map的成员,它将枚举映射到成员函数。如果函数的参数数量相同,我能够将枚举映射到所有函数。

enum STATE { OFF, ON, HIBERNATE, RESTART };
enum RETCODE { SUCCESS, FAIL, UNKNOWN, OUTOFBOUND };
class Engine
{
    Engine();
    RETCODE StateOn(double val);
    RETCODE StateOff(double val);
    RETCODE StateHibernate(double val);
    RETCODE StateRestart(double val);
private:
    const std::map<STATE, std::function<RETCODE(double)>> Map_State_FnPtr;
};
Engine::Engine() : Map_State_FnPtr {
        { STATE::ON, [=](double val) {return StateOn(val); } },
        { STATE::OFF, [=](double val) {return StateOff(val); } },
        { STATE::HIBERNATE, [=](double val) {return StateHibernate(val); } },
        { STATE::RESTART, [=](double val) {return StateRestart(val); } }
    }
{
    // c'tor body
}

但是我有一个场景,其中某些函数可以有零个或多个参数。在这种情况下,如何声明和构造映射变量?

class Engine
{
    Engine();
    RETCODE StateOn();                                              // No arguments
    RETCODE StateOff(double val);                                   // 1 argument
    RETCODE StateHibernate(double val, const std::string & data);   // Multiple arguments
    RETCODE StateRestart(double val);
private:
    const std::unordered_map<STATE, std::function<RETCODE()>> Map_State_FnPtr; // What should be the declaration?
};

对于这种情况还有其他建议吗?请帮忙。

您始终可以忽略参数

{
    { STATE::ON, [=](double, const std::string &) {return StateOn(); } },
    { STATE::OFF, [=](double val, const std::string &) {return StateOff(val); } },
    { STATE::HIBERNATE, [=](double val, const std::string & data) {return StateHibernate(val, data); } },
    { STATE::RESTART, [=](double val, const std::string &) {return StateRestart(val); } }
}

在这种情况下,如何声明和构造映射变量?

这在std::function是不可能的.此模板提供了一定数量的类型擦除,因为它可以使用函数指针、有状态 lambda 或指向成员函数的指针来构造,但存在一个不变的,即您用std::function实例近似的函数类型的签名。

您可以改为定义一个自定义聚合,其中包含参数列表的可能变体,例如

struct StateParams {
    double val;
    std::string data;
};

然后将函数签名更改为

RETCODE StateOn(const StateParams&);
RETCODE StateHibernate(const StateParams&);
// ...

std::map可以有value_type std::function<RETCODE(const StatemParams&>.