2012-10-13 64 views
1

給定一個類,它有兩個策略模板參數:C++,我可以不允許特定的策略組合嗎?

template<typename PolicyA, typename PolicyB> 
class widget; 

而下面可用的策略類A1,A2,A3,B1,B2,B3。如何傳達1s和2s彼此兼容,但A3僅與B3兼容?也就是說,只有下面的實例被允許:

widget<A1, B1> w11; // All valid. 
widget<A1, B2> w12; 
widget<A2, B1> w21; 
widget<A2, B2> w22; 
widget<A3, B3> w33; 

// No other combination allowed. 

我在使用中的專業化的std :: enable_if失敗的嘗試遭到了一個編譯錯誤:

template<typename A, typename B> 
class<A3, enable_if<is_same<B, B3>::value, B3>::type> 
{}; 
+0

專業化的語法看起來不正確。 (會檢查一個修復程序,但我附近沒有C++ 11編譯器) – Shiroko

回答

1
class A1; class A2; class A3; class B1; class B2; class B3; 

/// Generic type 
template <typename T1, typename T2> 
class widget 
{ 
    static_assert(std::is_same<T1, A3>::value^!std::is_same<T2, B3>::value, 
    "Incompatible policy types selected."); 
}; 

/// Some specialization 
template <> 
class widget<A1, A2> 
{ 
}; 

widget<A1, B1> w11; 
widget<A1, B2> w12; 
widget<A2, B1> w21; 
widget<A2, B2> w22; 
widget<A3, B3> w33; 
//widget<A1, B3> w13; // error C2338: Incompatible policy types selected. 
//widget<A3, B2> w32; // error C2338: Incompatible policy types selected. 
+0

靜態聲明中的條件可能有點偏離...我不確定,但我傾向於考慮'!(T1 == A3^T2 == B3)' –

+0

綠色檢查通過緊密的單線解決方案static_assert。 – screwnut

+0

@DavidRodríguez - dribeas:純粹的味道。 !(A^B),!A^B或A ^!B,無論如何......我認爲考慮到這種單行程的低複雜性,這些對於可讀性都沒有任何好處。 – Stacker

0

這聽起來像你已經知道specialized templates

無論如何,一個想法是爲不兼容的類型定義一個專門的模板,該模板會自動引發IncompatibleException或其他東西。

從技術上說,用戶可以定義類型,但它將不可用且完全明顯。

0

簡單的解決方案是對每個不兼容的情況做一個專門化,並讓它包含會引發編譯錯誤的東西。是這樣的:

template <> 
class widget<A1, B3> { 
    char error__policies_A1_and_B3_are_incompatible[0]; 
}; 

長度0將拋出編譯器關閉,並且「消息」的字符數組將某處出現在編譯錯誤。

+0

包含相鄰下劃線的標識符被保留用於實現。 – chris

+0

除了雙下劃線的問題之外,由於所需專業化的數量增加O(N * M),所以這是不可維護的,其中N是第一個參數的選項數量,M是第二個選項的數量論據。 –

相關問題