我有一个简单的注册表模式:
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/