Частичная специализация по умолчанию для шаблона с несколькими параметрами

Есть ли способ извлечь частичную специализацию по умолчанию из компилятора?

Скажи, что у меня есть этот шаблон с двумя параметрами:

template<typename A, typename B>
struct X {
A a;
B b;
};

и у меня также есть некоторый код, который использует шаблон одного параметра, например:

template<template<typename> class T, typename B>
struct make_T_of_B {
T<B> member;
};

Я хотел бы иметь возможность сказать:

make_T_of_B<X<int>, double> dummy;

где Х<ИНТ> принимается как шаблон с одним параметром. Это было бы эквивалентно этому шаблону:

template<typename B>
struct Y {
int a;
B b;
};

который выглядит как специализированный Х<Int, B> фактически ничего не меняя. Это похоже на специализацию по умолчанию — за исключением того, что специализация по умолчанию создает не другой шаблон, а фактический тип (другими словами, он всегда тотальный).

Я понимаю, что могу каскадировать аргументы шаблона

template<typename A>
struct Z1 {
// start from scratch
template<typename B>
struct Z2 {
A a;
B b;
};

// inherit from double template above
template<typename B>
struct X: ::X<A, B> {};
};make_T_of_B<Z1<int>::Z2, double> dummy1;
make_T_of_B<Z1<int>::X, double> dummy2;

но я нахожу это довольно трудным для чтения и не ясно выражаю свои намерения.

Спасибо.

0

Решение

Я неправильно понял ваш вопрос. Все, что вам нужно, это способ привязки первого параметра шаблона, который вы можете легко сделать следующим образом:

template <typename T> using Foo = X<int, T>;

Сейчас Foo<double> такой же как X<int, double>,

Без псевдонимов в стиле C ++ 11 вы можете добиться того же с немного большим количеством шаблонов:

template <typename T> struct Foo
{
typedef X<int, T> type;
};

Теперь вы используете Foo<double>::type,

2

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

Я бы использовал черту:

template <typename> struct applicator;

template <template <typename> class Tmpl, typename T>
struct applicator<Tmpl<T>>
{
template <typename A>
using rebind = make_T_of_B<Tmpl, A>;
};

Теперь вы можете сказать:

applicator<X<int>>::rebind<double> dummy;

Вы также можете переместить второй аргумент, A, в основной шаблон:

template <typename, typename> bpplicator;

template <template <typename> class Tmpl, typename T, typename A>
struct bpplicator<Tmpl<T>, A>
{
using type = make_T_of_B<Tmpl, A>;  // or "typedef make_T_of_B<Tmpl, A> type;"};

bpplicator<X<int>, double>::type dummy;

Это имеет то преимущество, что работает и в C ++ 03.

0

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