шаблоны — C ++, можно ли запретить определенную комбинацию политик?

Имеется класс, который принимает два параметра шаблона политики:

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.

Моя неудачная попытка использовать std :: enable_if в пределах специализации была встречена с ошибкой компиляции:

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

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.
1

Другие решения

Похоже, вы уже знаете о специализированные шаблоны.

В любом случае, идея состоит в том, чтобы определить специализированный шаблон для несовместимых типов, который автоматически выбрасывает IncompatibleException или что-то.

Таким образом, технически пользователь может определить тип, но это будет непригодно и совершенно очевидно.

0

Простое решение состоит в том, чтобы просто создать специализацию для каждого несовместимого случая и включить в нее что-то, что вызовет ошибку компиляции. Что-то вроде этого:

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

Массив char длиной 0 скинет компилятор, и где-то в ошибке компиляции появится «сообщение».

0
По вопросам рекламы [email protected]