2015-04-12 67 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>();