2011-02-09 4 views
0

Я хотел бы реализовать базовый класс с атрибутами размера, которые я уже знаю во время компиляции. Поэтому я решил использовать шаблон для этого базового класса. Следующий код компилируется и работает под управлением VC++ 9.0.Проблема с шаблоном C++

Определение класса в файле .h

template<int N> class BaseClass 
{ 
int* idx; 
int* incr; 
int* limit; 


public: 
BaseClass(void); 
~BaseClass(void); 

void LoopMethod(void); 

};

Реализация методов класса в .cpp файле

#include "BaseClass.h" 
#include<iostream> 

using namespace std; 

// instantiation 
template class BaseClass<2>; 


template<int N> BaseClass<N>::BaseClass(void) 
{ 
idx = new int [N]; 
incr= new int [N]; 
limit = new int[N]; 

for(int m = 0; m < N; m++) 
{ 
    idx[m] = 0; 
    incr[m] = 1; 
    limit[m] = 2; 
} 

} 

template<int N> BaseClass<N>::~BaseClass(void) 
{ 
} 


template<int N> void BaseClass<N>::LoopMethod() 
{ 
for(idx[N-1]; idx[N-1] < limit[N-1]; idx[N-1] += incr[N-1]) 
{ 
    cout << "LoopMethod Nr " << N-1 << " is called." << endl; 
} 

}

Реализация основной-функции:

#include<cstdlib> 
#include "BaseClass.h" 

using namespace std; 


int main() 
{ 
BaseClass<2> baseObj; 

baseObj.LoopMethod(); 


system("PAUSE"); 
return 0; 

} 

Теперь я хочу, чтобы гнездо для-петли из LoopMethod умножает размер атрибутов класса. То есть компилятор должен генерировать код, который я бы писать от руки, как

template<int N> void BaseClass<N>::LoopMethod() 
{ 
for(idx[0]; idx[0] < limit[0]; idx[0] += incr[0]) 
{ 
    for(idx[1]; idx[1] < limit[1]; idx[1] += incr[1]) 
    { 
     cout << "LoopMethod Nr " << 1 << " is called." << endl; 
    } 

    cout << "LoopMethod Nr " << 0 << " is called." << endl; 

} 
} 

Во всяком случае, я могу подсказать компилятор, чтобы сделать это, если я не объявить BaseClass быть классом шаблона. Код для этого будет выглядеть:

class BaseClass 
{ 


int* idx; 
int* incr; 
int* limit; 


public: 
BaseClass(void); 
~BaseClass(void); 

template<int M> void LoopMethod(void); 


}; 

Реализация методов класса в файле .cpp

#include "BaseClass.h" 
#include<iostream> 

using namespace std; 

template void BaseClass::LoopMethod<1>();   

BaseClass::BaseClass(void) 
{ 
idx = new int [2]; 
incr= new int [2]; 
limit = new int[2]; 

for(int m = 0; m < 2; m++) 
{ 
    idx[m] = 0; 
    incr[m] = 1; 
    limit[m] = 2; 
} 

} 

BaseClass::~BaseClass(void) 
{ 
} 

template<int M> void BaseClass::LoopMethod() 
{ 
for(idx[M]; idx[M] < limit[M]; idx[M] += incr[M]) 
{ 
    cout << "LoopMethod Nr " << M-1 << " is called." << endl; 
    LoopMethod<M-1>(); 

} 
} 

template<> void BaseClass::LoopMethod<0>(void) 
{ 
idx[0] = 0; 

for(idx[0]; idx[0] < limit[0]; idx[0] += incr[0]) 
{ 
    // do something 
    cout << "Now the inner loop is executed" << endl; 

} 

} 

Реализация основной-функции:

#include<cstdlib> 
#include "BaseClass.h" 

using namespace std; 


int main() 
{ 
BaseClass baseObj; 

baseObj.LoopMethod<1>(); 


system("PAUSE"); 
return 0; 
} 

Но решение Я ищу, чтобы иметь шаблонный шаблон с методом шаблона «LoopMethod», благодаря собственному параметру шаблона, который сообщает компилятору, сколько раз гнездо для цикла Loop. Я пробовал разные возможности, но безуспешно. Кто-нибудь имеет предложение или даже знает решение проблемы с этим шаблоном?

Заранее спасибо за вашу помощь,

Маркус.

+0

почему вы делаете этот шаблон? –

+6

Ваш вопрос ** слишком длинный **! Немногие люди здесь будут достаточно бесстрашными, чтобы прочесть его полностью! – Benoit

+0

Вашему классу нужен конструктор копирования и оператор присваивания копий. См. Этот раздел [FAQ] (http://stackoverflow.com/questions/4172722/). – fredoverflow

ответ

5

Есть много проблем, с шаблоном:

  • Что именно цель всего этого?
  • Почему вы инициализируете указатели новыми? Вы знаете размер во время компиляции, так почему бы просто не сделать их массивами?
  • Вы не удаляя память вы выделяющий
  • безопасности Exception, если новый сбой в одном из более поздних массивов
  • Осуществление, вероятно, должен быть в файле заголовка, если он не используется для очень немногих значений N, которые вы Instantiate
  • Лучше использовать классы, которые существуют, например, boost :: array
  • Рефакторинг из различных разделов.
0

Но решением, которое я ищу является иметь шаблонный класс с шаблоном методой «LoopMethod» по причине его собственного параметра шаблона, который рассказывает компилятора, сколько раз гнездо фор- Петля

Это то, что вы спрашиваете:

template<int N> 
struct X 
{ 
    template<int M> 
    void loop(); 
}; 

template<int N> 
template<int M> 
void X<N>::loop<M>() 
{ 
} 
+0

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

+0

Да, иди фигура ... –

Смежные вопросы