C++ C++;,我可以不允许特定的政策组合吗?

C++ C++;,我可以不允许特定的政策组合吗?,c++,templates,typetraits,C++,Templates,Typetraits,给定一个接受两个策略模板参数的类: template<typename PolicyA, typename PolicyB> class widget; 模板 类控件; 以及以下可用的保单类别A1、A2、A3、B1、B2、B3。如何传达1和2彼此兼容,而A3仅与B3兼容?也就是说,只允许以下实例化: widget<A1, B1> w11; // All valid. widget<A1, B2> w12; widget<A2, B1> w

给定一个接受两个策略模板参数的类:

template<typename PolicyA, typename PolicyB>
class widget;
模板
类控件;
以及以下可用的保单类别A1、A2、A3、B1、B2、B3。如何传达1和2彼此兼容,而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.
widget w11;//全部有效。
小部件w12;
小部件w21;
小部件w22;
小部件w33;
//不允许其他组合。
如果在专门化中遇到编译错误,则尝试使用std::enable_失败:

template<typename A, typename B>
class<A3, enable_if<is_same<B, B3>::value, B3>::type>
{};
模板
班
{};

听起来你已经知道了

无论如何,一个想法是为不兼容的类型定义一个专门的模板,该模板会自动抛出一个
不兼容异常


因此,从技术上讲,用户可以定义类型,但它将无法使用,而且非常明显。

听起来您已经知道了

无论如何,一个想法是为不兼容的类型定义一个专门的模板,该模板会自动抛出一个
不兼容异常


因此,从技术上讲,用户可以定义类型,但它将是不可用的,而且是完全明显的。

简单的解决方案是只对每个不兼容的情况进行专门化,并使其包含会触发编译错误的内容。大概是这样的:

template <>
class widget<A1, B3> {
  char error__policies_A1_and_B3_are_incompatible[0];
};
模板
类小部件{
字符错误策略A1和B3不兼容[0];
};

长度为0的字符数组将关闭编译器,并且“消息”将出现在编译错误中的某个位置。

简单的解决方案是对每个不兼容的情况进行专门化,并使其包含会触发编译错误的内容。大概是这样的:

template <>
class widget<A1, B3> {
  char error__policies_A1_and_B3_are_incompatible[0];
};
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.
模板
类小部件{
字符错误策略A1和B3不兼容[0];
};
长度为0的字符数组将使编译器关闭,“消息”将出现在编译错误的某个地方。

class A1;A2类;A3类;B1类;B2类;B3类;
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.
///泛型 模板 类小部件 { 静态断言(std::is_same::value^!std::is_same::value, “选择了不兼容的策略类型。”); }; ///专业化 模板 类小部件 { }; 小部件w11; 小部件w12; 小部件w21; 小部件w22; 小部件w33; //小部件w13;//错误C2338:选择了不兼容的策略类型。 //小部件w32;//错误C2338:选择了不兼容的策略类型。
A1级;A2类;A3类;B1类;B2类;B3类;
///泛型
模板
类小部件
{
静态断言(std::is_same::value^!std::is_same::value,
“选择了不兼容的策略类型。”);
};
///专业化
模板
类小部件
{
};
小部件w11;
小部件w12;
小部件w21;
小部件w22;
小部件w33;
//小部件w13;//错误C2338:选择了不兼容的策略类型。
//小部件w32;//错误C2338:选择了不兼容的策略类型。

您的专业化语法似乎不正确。(本应检查修复程序,但我附近没有c++11编译器)专用化的语法似乎不正确。(本应检查修复程序,但我附近没有c++11编译器)包含相邻下划线的标识符保留用于实现。除了双下划线的问题外,这是不可维护的,因为所需的专门化数量增加了O(N*M),其中N是第一个参数的选项数,M是第二个参数的选项数。包含相邻下划线的标识符保留用于实现。除了双下划线的问题外,这是不可维护的,因为所需的专门化数量增加了O(N*M),其中N是第一个参数的选项数,M是第二个参数的选项数。静态断言中的条件可能有点不正确。。。我不确定,但我倾向于思考
!(T1==A3^T2==B3)
绿色检查,通过静态测试确定紧密的一层溶液。@David Rodríguez-dribeas:纯味觉物质!(A^B)!A^B,或A^!B、 不管怎样。。。考虑到这种单行程序的低复杂度,我认为它们在可读性方面没有任何好处。。。我不确定,但我倾向于思考
!(T1==A3^T2==B3)
绿色检查,通过静态测试确定紧密的一层溶液。@David Rodríguez-dribeas:纯味觉物质!(A^B)!A^B,或A^!B、 不管怎样。。。考虑到这一行代码的低复杂性,我认为这些代码在可读性方面没有任何好处。