2016-03-24 27 views
0

是否可以實現類似下面的Variadically模板結構/如何提高::變體實施

DifferentTypesInOne<string, int, double> variant_obj; 

如果你variant_obj具有字符串類型,整型變量和雙擊它的效果。

我知道這與boost::variant相似。之前我搜索了一些有關它的問題,但是我無法找到一個解釋來解釋這個類如何使用可變參數模板來存儲所有類型的元素。特別是我在問我如何去定義一個struct,它有所有給定類型的變量和一個表示當前哪個變量很重要的成員變量。

謝謝!

+0

對於一個變體,無論是與工會遞歸,或者你有一塊存儲和使用位置新。 –

+0

我只是很難理解如何在結構中包含可變參數模板列表中的許多類型的元素 – Curious

+0

該評論是否有意義? – Curious

回答

2

粗略地說,

template<class... Ts> 
struct variant_storage {}; 

template<class T, class... Ts> 
struct variant_storage<T, Ts...>{ 
    union { 
     T head; 
     variant_storage<Ts...> tail; 
    }; 
}; 

template<class... Ts> 
struct variant { 
    int index; 
    variant_storage<Ts...> storage; 
}; 

這是一個草圖;詳情thesearticles是一個很好的閱讀。

如果您不需要constexpr -ness,則可以將std::aligned_union_t<0, Ts...>存儲爲存儲,並使用更新更簡單的placement new。

+0

哇,這真棒。你能解釋一下這裏發生了什麼嗎? – Curious

+0

@Curious:它是遞歸,模板元編程的基本工具(以及一般編程)。 –

+0

等待它不是遞歸。這是編譯時遞歸,這不是真正的遞歸權嗎? – Curious

1

C++ 11提供了一個模板類型,std::aligned_union,它帶有一個類型列表。 aligned_union::type是一種具有足夠存儲空間和對齊的類型,可以作爲任何給定類型的存儲。

這就是您如何爲數據創建存儲。除此之外,您需要的只是一個整數,用於指示將值存儲在那裏。

template<typename ...Types> 
struct variant 
{ 
private: 
    uint8_t index; 
    typename std::aligned_union<Types...>::type storage; 
}; 

可以使用放置new到各個元件分配給特定類型的,由storage提供的存儲範圍內。

+0

你會如何匹配類型與索引? – Curious

+0

等待你如何將該類型與索引匹配? – Curious