Ошибка шаблона C ++: «недопустимый явно заданный аргумент для параметра шаблона» - PullRequest
0 голосов
/ 21 января 2020

У меня есть несколько тысяч строк кода, которые я пытаюсь реорганизовать, и я могу значительно сократить объем дублирования кода, объединив несколько различных классов в один класс, который обрабатывает вещи, вызывая указатель на внешние классы друзей.

Я столкнулся с проблемой в том, что у меня есть переменная 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. Это изменяется в зависимости от физические свойства моделируемого сигнала. В нескольких различных местах кода используются функции линейной алгебры.)

1 Ответ

0 голосов
/ 21 января 2020

Я не верю и не помню точный стандартный термин, что const int Nsides; является действительным аргументом для создания шаблона. Это то, что компилятор пытается вам сказать, и именно то, что вы исправляете, сделав этот шаблон сам по себе.

...