Это невозможно в вашем текущем интерфейсе с использованием параметров, отличных от типа.
Вы можете принять параметры типа вместо и завернуть значения в std::integral_constant
:
template<class X, class Y, class Z>
class A { /* stuff */ };
// use as:
A<std::integral_constant<Color, Color::Red>,
std::integral_constant<ShowAxes, ShowAxes::True>,
std::integral_constant<ShowLabels, ShowLabels::True>> a;
Это довольно многословен, так что вы могли бы рассмотреть возможность написания макроса:
#define AS_IC(Value) std::integral_constant<decltype(Value), Value>
и переписать в виде
A<AS_IC(Color::Red), AS_IC(ShowAxes::True), AS_IC(ShowLabels::True)> a;
Извлечение значения нужного типа из спискаs прост:
template<class Result, class...>
struct extract;
template<class Result, Result Value, class... Tail>
struct extract<Result, std::integral_constant<Result, Value>, Tail...> : std::integral_constant<Result, Value> {};
template<class Result, class Head, class... Tail>
struct extract<Result, Head, Tail...> : extract<Result, Tail...> {};
Затем вы можете сделать
// inside the definition of A
static constexpr Color col = extract<Color, X, Y, Z>::value;
Demo.
Это не, однако, порождают один и тот же класс, но вы можете сделать шаблон A_impl
класс, который ведет себя, как ваш A
с параметрами не типа, и содержит фактическую реализацию, а затем сделать A
шаблон псевдоним:
template< Color, ShowAxes, ShowLabels >
class A_impl
{/* stuff */};
template<class X, class Y, class Z>
using A = A_impl<extract<Color, X, Y, Z>::value,
extract<ShowAxes, X, Y, Z>::value,
extract<ShowLabels, X, Y, Z>::value>;
Теперь данный
A<AS_IC(Color::Red), AS_IC(ShowAxes::True), AS_IC(ShowLabels::True)> a;
A<AS_IC(Color::Red), AS_IC(ShowLabels::True), AS_IC(ShowAxes::True)> b;
a
и b
имеют одинаковый тип. Demo.
В качестве альтернативы, вы можете также использовать decltype
и перегружать шаблоны функций, но это требует добавления шаблона объявление функции для каждого возможного порядка типов:
template< Color c, ShowAxes a, ShowLabels l>
A<c,a,l> A_of();
template< ShowAxes a, ShowLabels l, Color c>
A<c,a,l> A_of();
// etc.
decltype(A_of<Color::Red, ShowAxes::True, ShowLabels::True>()) a1;
decltype(A_of<ShowAxes::True, ShowLabels::True, Color::Red>()) a2;
C++ шаблона класса специализации? –
@BryanChen вы не можете изменять типы параметров со специализацией –
Я не хочу менять типы параметров. Специализация - хорошая идея, но у меня есть 3! = 6 перестановок. Более того, я собираюсь добавить дополнительные параметры. –