У меня есть несколько тысяч строк кода, которые я пытаюсь реорганизовать, и я могу значительно сократить объем дублирования кода, объединив несколько различных классов в один класс, который обрабатывает вещи, вызывая указатель на внешние классы друзей.
Я столкнулся с проблемой в том, что у меня есть переменная num_var
, которая подсчитывает количество переменных, которые будут использоваться в вычислениях, и это меняется в зависимости от внешнего класса друга. Это число определило размер многих моих массивов. С массивами я часто выполняю линейную алгебру с внешними функциями, и эти функции являются функциями шаблона с параметром шаблона, равным размеру массива, num_var
. Раньше у меня было это static
, но я больше не могу этого делать.
Теперь я получаю ошибку, подобную этой:
candidate template ignored: invalid explicitly-specified argument for template parameter
Ниже приведена очень простая программа, которая дублирует ошибка компилятора для гораздо более простой системы:
#include <iostream>
enum Color {red=0, blue, green};
class Side {//the side of a shape, which can be a color
public:
Color color;
friend class Shape;
};
//this function adds numerical value of side colors and prints a value
template <size_t N> int sideNamer(Side sides[N]){
int count = 0;
for(int i=0; i<N; i++) count += sides[i].color;
std::cout << "My sides add to " << count << "\n";
return count;
};
class Shape { //can have an arbitrary number of sides, each a different color
public:
const int Nsides;
Side *sides;
//constructor sets the number of sides and gives a color to each side
Shape(int N, Color *colors) : Nsides(N){
sides = new Side[Nsides];
for(int i=0; i<Nsides; i++) sides[i].color = colors[i];
};
~Shape(){ delete[] sides;};
//name the sum of the sides
void nameMySides(){
sideNamer<Nsides>(sides);
}
};
int main(){
//make a triangle: should add to 3
Color myTriangleColors[3] = {red, blue, green};
Shape myTriangle(3, myTriangleColors);
myTriangle.nameMySides();
//make a square: should add to 2
Color mySquareColors[4] = {red, red, blue, blue};
Shape mySquare(4, mySquareColors);
mySquare.nameMySides();
}
Это дает мне ту же ошибку о недопустимом явно указанном аргументе для параметра шаблона.
Когда я изменяю объявление Shape
быть шаблоном класса, как в
template <size_t N> class Shape {
public:
static const int Nsides = N;
Side *sides;
Shape(Color *colors) {
sides = new Side[Nsides];
for(int i=0; i<Nsides; i++) sides[i].color = colors[i];
};
~Shape(){ delete[] sides;};
void nameMySides(){
sideNamer<Nsides>(sides);
}
};
и mutando mutandis , тогда проблем нет, и это работает. К сожалению, я не могу сделать это в моей настоящей программе, потому что в каком-то другом месте кода у меня есть другой класс, который содержит массив указателей на объекты "Shape
", и я не могу указать "size_t" в этот пункт в коде, поэтому я не могу использовать там шаблоны.
Есть ли что-то еще, что я могу сделать, чтобы функция шаблона работала? Кроме того, если бы это позволило мне объявить массив Side
как Side sides[Nsides]
вместо Side *sides
, это также было бы очень полезно.
Как мне работать с аргументом шаблона, когда я не могу использовать шаблон класса или a static const
? Или есть способ заставить класс шаблона работать в более ранней части программы? Должен ли я просто переписать функции линейной алгебры?
Заранее спасибо.
(PS Мой реальный класс с проблемой называется Mode
, представляющий собственную моду в физической задаче. имеет указатель на абстрактный класс с именем ModeDriver
, а отдельные дочерние элементы ModeDriver
могут иметь 2, 4, 8, ... переменных, число которых хранится в переменной с именем num_var
. Это изменяется в зависимости от физические свойства моделируемого сигнала. В нескольких различных местах кода используются функции линейной алгебры.)