参考全局的模板函数(取决于类型)

时间:2015-05-26 20:07:05

标签: c++ templates stl

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

// 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”)会知道检查exampleClasses映射吗?

1 个答案:

答案 0 :(得分:0)

你的问题有两个问题,我将解决第一个问题。您可能想要的是将所有函数组合为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);