2012-10-13 58 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是第二个选项的数量论据。 –

相关问题