2015-04-12 36 views
2

首先,我非常喜欢单例的延迟初始化模式。我用它以如下方式来获得不同类型的数据具有不同的值的类型(该例子被简化):非静态成员变量创建类似于C++中的静态单例创建

class A 
{ 
    template<typename T> 
    const T& getData() const 
    { 
     static T data; 
     return data; 
    } 
} 

我知道data变量未连接到任何类实例和它的存在直到节目结束。

但我现在想要的是,类A的每个实例应该以非静态方式保存变量,并且仍然应该具有调用.getData<bool>()或任何其他数据类型的灵活性,而无需指定类定义中每种可能的数据类型。

这可能吗?我还没有想出实现这一点的想法。

我想的东西用等的容器:

template<A*, typename T> 
class DataContainer 
{ 
    T data; 
} 

有了一个可以将代码扩展到:

class A 
{ 
    template<typename T> 
    const T& getData() const 
    { 
     static DataContainer<this, T> container; 
     return container.data; 
    } 
} 

但是,这并不编译。

有没有人有想法如何实现?

回答

2

这里有一个想法,用Boost.any:

#include <typeinfo> 
#include <type_index> 
#include <unordered_map> 
#include <boost/any.hpp> 

struct ThingGetter 
{ 
    template <typename T> 
    T & get() 
    { 
     auto key = std::type_index(typeid(T)); 
     auto it = things.find(key); 

     if (it == things.end()) 
     { 
      it = things.emplace(key, boost::any(T())).first; 
     } 

     return boost::any_cast<T&>(*it); 
    } 

    std::unordered_map<std::type_index, boost::any> things; 
}; 

这个简单的版本假定每个类型可以是值初始化,如果存在所请求的类型没有内容,建立一个值初始化值。其他实现可能会返回一个指针,该指针可能为空,并具有单独的插入接口。

用法:

ThingGetter mythings; 

mythings.get<bool>() = true; 
mythings.get<double>() = 1.5; 
return mythings.get<int>();