Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;带有外部实现的静态模板_C++_Templates_Design Patterns - Fatal编程技术网

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

C++ C++;带有外部实现的静态模板,c++,templates,design-patterns,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, c

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

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);
};
我想这样使用注册表:

Registry::Set(new Foo());

注册表::Get();
如何使用外部实现模拟静态模板?

我不会使用OBJECT_DEF()的hack

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

然后,我将使用boost any对象将这些信息很好地存储在地图中

我没有检查这个。
但注册器现在可以用于任何类型

#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";
}
#包括
#包括
#包括
#包括
#包括
类寄存器
{
静态std::地图数据;
公众:
//如果您只想存储指针,那么:
//将输入参数改为Set()为T*
//将Get()的输出更改为T*并修改any_强制转换。
// 
//如果您只是存储指针,我也会修改映射
//成为boost::pointer\u映射,以便转移所有权
//记忆也被清理了。
模板
静态无效集(T常量和值)
{
data[std::string(typeid(T).name())]=boost::any(value);
}
模板
静态T Get()
{
返回boost::any_cast(数据[std::string(typeid(T).name()))];
}
};
std::map Register::data;
int main()
{
//目前,该行将泄漏,因为register没有所有权。
寄存器::Set(新int(1));
//这条线很好用。
寄存器::Set(int(5));

std::cout FYI:您的宏定义不正确:因为“Name”是一个参数,“Name”函数名也将被替换,我认为这不是您想要的行为。是的,我知道这样的解决方案。我希望这将是一个全局对象注册表。@den bardadym:只需将方法设置为静态。更新的解决方案以反映需求。
Registry::Get<Foo>();
#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";
}