2011-10-12 48 views
5

我有一組有一個一對一的關係相關的類型,例如:地圖兩種類型在編譯時

TypeA ---> Type1 
TypeB ---> Type2 
TypeC ---> Type3 

我在編譯時知道這些關係。

然後,我有一個依賴於這兩種類型的模板類:

template<class T1,class T2> 
class MyClass 
{ 
    T1 foo; 
    T2 bar; 
}; 

現在,我的媒體庫的用戶將鍵入類似:

MyClass<TypeA,Type1> x; 

這是不方便的,因爲有這兩種類型之間的依賴關係,並且它應該足以讓用戶只指定第一種類型。

而且,混合兩種應該是不可能的:

MyClass<TypeA,Type2> y; //it should not compile 

我不是很熟悉模板元編程,我得到的印象是,這是可行的任務,但我可能是錯的。

的參與種類的數量是很大的,但是我很高興地運行一個腳本,如果需要生成代碼。

你知道,如果它是可能的,或者我在浪費時間?你有什麼想法可以指出我正確的方向嗎?

回答

6
template<class T> 
struct get_mapped; 

template<> 
struct get_mapped<TypeA>{ 
    typedef Type1 type; 
}; 

// and so on.... 


template<class T> 
class MyClass{ 
    typedef typename get_mapped<T>::type T2; 

    T foo; 
    T2 bar; 
}; 
3

爲什麼不創建一個包裝類型:

template <typename T1, typename T2> 
struct wrapper 
{ 
    typedef T1 type1; 
    typedef T2 type2; 
}; 

typedef wrapper<TypeA, Type1> TypeX; 
typedef wrapper<TypeB, Type2> TypeY; 
typedef wrapper<TypeC, Type3> TypeZ; 

然後用戶說,MyClass<TypeX>;,並且定義:

template <typename T> 
class MyClass 
{ 
    typename T::type1 foo; 
    typename T::type2 bar; 
}; 

如果你想防止模板的誤用,使用部分專精:

template <typename> class MyClass; // undefined 

template <typename S, typename T> 
class MyClass<wrapper<S,T>> 
{ 
    S foo; 
    T bar; 
}; 

這種方法可以很容易地擴展到進一步包括編譯時數據到包裝類中。或者,您可以使用std::pair,並使用成員類型first_typesecond_type代替。

5
template<class T> struct TypeLetter2TypeDigit; 

template<> struct TypeLetter2TypeDigit<TypeA> { typedef Type1 type; }; 
template<> struct TypeLetter2TypeDigit<TypeB> { typedef Type2 type; }; 
template<> struct TypeLetter2TypeDigit<TypeC> { typedef Type3 type; }; 


template<class T1> // Type2 is not needed 
class MyClass 
{ 
    // Type2 is deduced. 
    typedef typename TypeLetter2TypeDigit<T1>::type T2; 
    T1 foo; 
    T2 bar; 
}; 
+0

作了一些更正。看看它是否正確。 (另外,你真的需要這樣一個長名字TypeLetter2TypeDigit嗎?恕我直言,像'TypeMap'就足夠了。) – iammilind

+0

@iammilind。謝謝。需要長名稱以顯示我想要的內容。您或OP可以使用任何名稱。 –