具有外部实现的 C++ 静态模板

标签 c++ templates design-patterns

我有一个简单的注册表模式:

class Object
{
//some secondary simple methods
};

#define OBJECT_DEF(Name) \
 public: \
  static const char* Name() { return Name; } \
 private:


class Registry
{
 struct string_less {
  bool operator() (const std::string& str1, const std::string& str2) {
   for(int i = 0; i < str1.size() && i < str2.size(); ++i) {
    if(str1[i] != str2[i])
     return str1[i] < str2[i];
   }
   return str1.size() < str2.size();
  }
 };

 typedef boost::shared_ptr < Object> ptrInterface;
 typedef std::map < std::string,  ptrInterface, string_less > container;
 container registry;

 static Registry _instance;

 ptrInterface find(std::string name);

protected:
 Registry () {}
 ~Registry () {}


public:


 template < class T >
 static T* Get(); // I want to write so !!!

 template < class T >
 static bool Set(T* instance, bool reSet = false);
};

如果我有一个扩展对象的类:

class Foo : public Object {
    OBJECT_DEF("foo");
//smth
};

我想这样使用注册表:

Registry::Set(new Foo());

Registry::Get<Foo>();

如何使用外部实现模拟静态模板?

最佳答案

我不会使用 OBJECT_DEF() 的 hack

每个类都有一个唯一的名称(由编译器定义),可以通过 type_info 访问

然后我会使用 boost any 对象将此信息很好地存储在 map 中。

我还没有检查过这个。
但是 register 现在应该适用于任何类型。

#include <map>
#include <boost/any.hpp>
#include <typeinfo>
#include <string>
#include <iostream>

class Register
{
    static std::map<std::string, boost::any>       data;

    public:
        // If you just want to store pointers then:
        //     alter the input parameter to Set() to be T*
        //     alter the output of Get() to be T* and modify the any_cast.
        // 
        // If you are just storing pointers I would also modify the map
        // to be a boost::pointer_map so that ownership is transfered
        // and memory is cleaned up.
        template<typename T>
        static void Set(T const& value)
        {
            data[std::string(typeid(T).name())] = boost::any(value);
        }

        template<typename T>
        static T Get()
        {
            return boost::any_cast<T>(data[std::string(typeid(T).name())]);
        }


};

std::map<std::string, boost::any>       Register::data;

int main()
{
    // Currently this line will leak as register does not take ownership.
    Register::Set(new int(1));

    // This line works fine.
    Register::Set(int(5));

    std::cout << *(Register::Get<int*>()) << "\n";
    std::cout << Register::Get<int>() << "\n";
}

关于具有外部实现的 C++ 静态模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3398794/

相关文章:

java - 选择设计模式时的困境

C++ 加载 DLL

c++ - 将整数文字初始化为 std::size_t

c++ - 如何根据其位将有符号整数值转换为无符号整数?

c++ - 使用 C++ 模板时表达约束

c++ - 使用模板化节点的模板化列表类中缺少类型说明符

c++ - 有什么方法可以更快地处理 "predictable branches"吗?

c++ - 是否可以在派生类中选择性地定义类型

java - 如何在组件的设计阶段防止内存泄漏?

language-agnostic - OOP:何时创建派生类,何时使用条件实现功能?