如何自动将处理程序添加到全局映射

How to automatically add handler to the global map?

本文关键字:全局 映射 添加 程序 何自动 处理      更新时间:2023-10-16

>我有应用程序单例有方法

void addHandler(const std::string& command, std::function<std::string (const std::string&)> handler)

我想使用这样的处理程序创建很多 cpp 文件

//create_user_handler.cpp
Application::getInstance()->addHandler("create_user", [](std::string name) {
   UserPtr user = User::create(name);
   return user->toJson();
});

如何从我的 cpp 文件中自动调用它?

我尝试从void addHandler更改为bool addHandler而不是使用

namespace {
  bool b = Application::getInatance()->addHandler......
}

但它对我不起作用

乌达特它现在可以工作了,但是是否可以以更好的方式完成,没有未使用的布尔变量?

利用静态类实例化。

伪代码 -添加注册器类。

class Registrator {
   template <typename Func>
   Registrator(const std::string& name, Func handler) {
     Application::getInstance()->addHandler(name, handler);
   }
};

在每个 cpp 文件中,创建一个静态类对象:

test.cpp
static Registrator test_cpp_reg("create_user", [](std::string name) {
   UserPtr user = User::create(name);
   return user->toJson();
});

我假设 addHandler() 应该返回布尔值? 否则,无法分配给 bool 变量。

若要删除 addHandler 的布尔返回值,请从其他某个类的构造函数进行调用,而这些构造函数又以静态方式实例化。

这种代码可以工作,但很棘手。 问题在于,在 C/C++ 中,静态存储初始值设定项的顺序是未定义的。 因此,虽然允许静态初始值设定项调用任何代码,但如果该代码引用尚未初始化的数据,它将失败。 不幸的是,失败是不确定的。 它可能会工作一段时间,然后您更改一些编译器标志或模块顺序,然后 splat!

一个技巧是使用哑指针实现 getInstance() 的实例状态,因为它总是在任何静态初始值设定项触发之前初始化为零 (null)。 例如,以下代码将在主启动之前打印"添加的 foo":

#include <string>
#include <functional>
#include <map>
#include <iostream>
class Application {
public:
    static Application* getInstance() {
        // Not thread-safe!
        if (instance == 0) {
            instance = new Application;
        }
        return instance;
    }
    typedef std::function<std::string(const std::string&)> HANDLER;
    typedef std::map<std::string, HANDLER> HANDLER_MAP;
    bool addHandler(const std::string& command, HANDLER handler) {
        handlerMap.insert(HANDLER_MAP::value_type(command, handler));
        std::cout << "Added " << command << "n";
        return true;
    }
    HANDLER_MAP handlerMap;
    static Application* instance;
};
Application* Application::instance;
std::string myHandler(const std::string&) { return "";  }
bool b = Application::getInstance()->addHandler("foo", myHandler);
int main()
{
    return 0;
}