引用全局变量的模板函数(取决于类型)

Template Functions Referring to Globals (Depending on Type)

本文关键字:取决于 类型 函数 全局变量 引用      更新时间:2023-10-16

对于代码库中的许多类,我需要维护一个全局映射,以便查找该类的实例。例子:

// In ExampleClass.h
ExampleClass *getExampleClass(std::string name);
std::unordered_map<std::string, ExampleClass *> &getAllExampleClasses();
bool addExampleClass(std::string name, ExampleClass *e);

// In ExampleClass.cpp
std::unordered_map<std::string, ExampleClass *> exampleClasses;
ExampleClass *getExampleClass(std::string name) {
   return exampleClasses.find(name) == exampleClasses.end() ? nullptr : exampleClasses.find(name)->second;
}
std::unordered_map<std::string, ExampleClass *> &getAllExampleClasses() {
   return &exampleClasses;
}
bool addExampleClass(std::string name, ExampleClass *e) {
   if (exampleClasses.find(name) == exampleClasses.end()) {
       exampleClasses[name] = e;
       return true;
   }
   else
       return false;
}

在这样做了几个类之后,我决定把所有这些全局变量和方法放在global.cpp/h中,并使用模板函数。

template <class T> T *get(std::string name);
template <class T> std::unordered_map<std::string, T *> &getAll();
template <class T> bool add(std::string name, T *);

是否有一种方法在模板函数定义中指定要根据类型查找的全局映射?所以get("name")将知道检查exampleclass映射?

你的问题有两个问题,我回答第一个。您可能想要的是将所有函数分组为单个类模板中的static。请注意,您的函数的实现非常低效,因此我也为您修复了这个问题:

template <typename T>
using RegistryMap = std::unordered_map<std::string, T*>;
template <typename T>
class Registry {
    static RegistryMap<T> registry;
public:
    static T* get(const std::string& name) {
        auto it = registry.find(name);
        return it == registry.end() ? nullptr : it->second;
    }
    static const RegistryMap<T>& getAll() {
        return registry;
    }
    static bool add(const std::string& name, T* object) {
        T*& store = registry[name];
        if (store) {
            return false;
        }
        else {
            store = object;
            return true;
        }
    }
};
template <typename T>
RegistryMap<T> Registry<T>::registry;

对于你原来的例子,你可以这样写:

Registry<Example>::get("name", &some_example);