Шаблонная специализация & amp; Частичная специализация

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

У меня есть шаблон класса:

template <class T, int x, int y>
class Z {
T **array[x][y];
public:
Z();
void print();
//and other methods
};

Мне необходимо:

1) Только Z, где x = 2 и y = 2, должны иметь открытый метод void J ()

2) Для символов Z из x = 2 и y = 2 J что-то сделает; для всего остального он делает что-то еще

3) Только для Z, где T — char, массив будет инициализирован до некоторого значения. Для всего остального это 0

Естественно, это работает:

template<class T, int x, int y>
Z<T,x,y>::Z<T,x,y>() { //initialize to 0 }

Но это не так:

template<int x, int y>
Z<char,x,y>::Z<char,x,y>() { //initialize to something}

И также (предположим, J существует) это не работает:

template <class T>
void Z<T,2,2>::J() { //something }

Мой вопрос:

Есть ли какой-нибудь простой способ для реализации вышеуказанных пунктов? Мне нужно сохранить все другие методы в Z. Было бы полезно дать подсказку или указать правильное направление (возможно, я пропустил вопрос, поскольку их много).

Благодарю.

4

Решение

Кажется, вы хотите определить только некоторые функции некоторых специализаций: если print() не меняется между char специализация и общий случай, кажется, что вы не хотите переопределять его.

// What you want to do (illegal in C++)
template<int,typename T>
struct Z
{
T myValue;
Z();
void print() { /* ... */ }
};

template<int i, typename T>
Z<i,T>::Z() { /* ... */ }

template<int i>
Z<i,char>::Z() { /* ... */ }

Тем не менее, это не работает так. Частичные или полные специализации класса не имеют почти ничего общего, кроме «прототипа» параметров шаблона:

// The two following types have only two things related: the template parameter is an int,
// and the second type is a full specialization of the first. There are no relations between
// the content of these 2 types.
template<int> struct A {};
template<> struct A<42> { void work(); };

Вы должны объявить и определить каждую (частичную) специализацию:

// Fixed example
template<int,typename T>
struct Z
{
T myValue;
Z();
void print() { /* ... */ }
};
template<int i, typename T>
Z<i,T>::Z() { /* ... */ }

// Specialization for <all-ints,char>
template<int i>
struct Z<i,char>
{
char myValue;
char othervalue;
Z();
void print() { /* Same code than for the general case */ }
};

template<int i>
Z<i,char>::Z() { /* ... */ }

Единственный способ избежать дублирования кода — использовать наследование черты:

// Example with the print function
template<typename T>
struct print_helper
{
void print() { /* ... */ }
};

// Fixed example
template<int,typename T>
struct Z : public print_helper<T>
{
T myValue;
Z();
};
template<int i, typename T>
Z<i,T>::Z() { /* ... */ }

// Specialization for <all-ints,char>
template<int i>
struct Z<i,char> : public print_helper<char>
{
char myValue;
char othervalue;
Z();
};

template<int i>
Z<i,char>::Z() { /* ... */ }

Вы не можете делать то, что вы хотите без дублирования на данный момент (функция удаления дублирования кода static if и был предложен для следующего стандарта C ++, см. n3322 а также n3329).

5

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

Вы можете взглянуть на этот курс http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-5-of-n

Хотя невозможно определить частичную специализацию для шаблонов функций, вы можете определить частичную специализацию для шаблона класса или структуры.

template<typename T> struct helper {
static void doThingy(){}
};

template<typename X> struct helper<X*> {
static void doThingy(){}
};

Helper(double*)::doThingy();

В этом примере вы хотите специализировать поведение в doThingy () только тогда, когда тип в шаблоне является типом указателя. Вы не можете использовать перегрузку метода doThingy () в этом случае. Это потому, что вы не можете перегрузить функцию без аргументов. Но вы можете иметь частичную специализацию помощника структуры. В специализированном шаблоне вы реализовали желаемое поведение для doThingy ().

0

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