2016-09-26 97 views
3

假設我們有一個維護一組元素的數據結構Foo。應該可以根據需要將屬性與元素相關聯。這些屬性應該分別存儲在一個單獨的向量中。我們通過可變參數模板來實現這一點:如何在同一個可變參數模板的不同實例之間進行轉換?

#include <vector> 

template <typename ...Attrs> 
struct Foo : public Attrs... { 
    Foo(int n = 0) { 
    using PackExpansionT = int[]; 
    PackExpansionT{0, (Attrs::values.resize(n), 0)...}; 
    } 
}; 

struct AttrA { std::vector<int> values; }; 
struct AttrB { std::vector<float> values; }; 
struct AttrC { std::vector<double> values; }; 

int main() { 
    Foo<AttrA, AttrB> foo; // Maintains set of elements with two attributes each. 
}; 

現在,我想用下面的語義的轉換操作符:

Foo<AttrB, AttrC> bar = foo; // bar.AttrB::values should be a copy of foo.AttrB::values. 

這僅僅是一個例子。通常,轉換運算符應該能夠將具有任意屬性的Foo轉換爲具有任意屬性的另一個Foo。應該複製與Foo相關的屬性。不與兩者關聯的屬性可以保持默認。但是,我不知道如何實現它。

template <typename ...OthersAttrs> 
    operator Foo<OthersAttrs...>() const { 
    // ...? 
    } 
+1

你是做什麼關於與關聯的屬性目標但不是來源? – merlin2011

+0

現在不重要。也許他們的價值被設定爲某種默認值,或許他們的價值是簡單的未定義的。 – user1494080

+0

@ user1494080這是非常重要的:你想從'foo'複製初始化後'bar'是什麼? – Barry

回答

5

我們可以做一堆獨立的決定。首先,讓我們添加一個構造函數,以便我們可以構建從它的屬性成分Foo

Foo(Attrs const&... attrs) 
: Attrs(attrs)... 
{ } 

接下來,爲每個屬性在Others,我們要麼垂頭喪氣this到合適的類型,如果可能,或者返回一個默認構造的一個否則:

template <typename... Others> 
operator Foo<Others...>() const { 
    return {get_attr<Others>(this)...}; 
} 

其中:

template <class T> 
T const& get_attr(T const* v) const { 
    return *v; 
} 

template <class T> 
T get_attr(...) const { 
    return T{}; 
} 
2

大綱我能想到的:

template <typename ...OthersAttrs> 
operator Foo<OthersAttrs...>() const 
{ 
    Foo<OthersAttrs...> rv(GetNSomehow()); 
    (int[]){(CopyAttr<Attrs>(&rv), 0)...}; 
    return rv; 
} 

template<typename Attr> 
void CopyAttr(Attr *rv) const // Overload A 
{ 
    rv->values = ((const Attr*)this)->values; 
} 

template<typename Attr> 
void CopyAttr(...) const // Overload B 
{ 

} 

這裏的竅門是通過屬性去屬性。
如果rv具有該屬性,則將選擇第一個重載並將其複製。
否則,第二次重載將被選擇,將無所事事。

相關問題