Работа вокруг, чтобы неспособность сделала шаблоны функций виртуальными?

У меня есть вершина абстрактного класса, которая представляет n-кортеж. Элемент вершины может иметь любой тип: т.е., компоненты вершины могли иметь интервал типа, интервал, плавание или что-то. Поскольку вершина может иметь произвольное число размеров, я думал о том, чтобы заставлять класс иметь метод set компонента как так:

class vertex {
    public:
        template <class T>
        virtual void setComp(int componentnumber, T value) = 0;
};

Конечно, C++ не разрешает шаблоны виртуальной функции. Так: как я должен делать это? Я также не знаю, как я должен писать метод считывания для вершин.

Спасибо.

1
задан amc 23 June 2010 в 14:56
поделиться

5 ответов

Ну, обычно у вас должен быть тип вершины в качестве параметра шаблона, чтобы его можно было правильно сохранить:

template<typename T, size_t NumAxes = 3>
class vertex {
    private:
        T comp[NumAxes];
};

В этом случае нет необходимости в виртуальном методе, поскольку вы можете просто использовать приведение типов C ++ для выполнения work:

template<typename T, size_t NumAxes = 3>
class vertex {
public:
    template <typename U>
    void setComp(size_t index, U value) { comp[index] = static_cast<T>(value); }
private:
    T comp[NumAxes];
};

Теперь, если вы хотите, чтобы он был виртуальным, потому что вы хотите, чтобы подклассы могли с чем-то связываться (например, регистрировать каждое изменение значения), вам нужно определить не шаблонную функцию:

template<typename T, size_t NumAxes = 3>
class vertex {
public:
    template <typename U>
    void setComp(size_t index, U value)
    { _setComp(index, static_cast<T>(value)); }
protected:
    T comp[NumAxes];
    virtual void _setComp(size_t index, T value) 
    { comp[index] = value; }
};

template<typename T, size_t NumAxes = 3>
class logged_vertex: public vertex<T, NumAxes> {
protected:
    virtual void _setComp(size_t index, T value);
};

template<typename T, size_t NumAxes = 3>
void logged_vertex<T, NumAxes>::_setComp(size_t index, T value)
{   cout << "Index " << index << " changed from " << comp[index];
    vertex<T, NumAxes>::_setComp(index, value);
    cout << " to " << comp[index] << endl;
}
2
ответ дан 2 September 2019 в 23:33
поделиться

Это очень странное сочетание объектно-ориентированного программирования и общего программирования. Я думаю, тебе стоит выбрать одно или другое.

Сделайте класс вершины шаблоном или , определите базовый класс для параметра «значение» и получите классы обработчиков пользовательского типа.

0
ответ дан 2 September 2019 в 23:33
поделиться

Используйте полиморфизм вместо шаблонов.

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

Реализация этих решений предполагает использование boost::any или boost::variant для экономии времени.

0
ответ дан 2 September 2019 в 23:33
поделиться

Поскольку вершина может иметь произвольное число измерений - почему бы не сделать ее

template<size_t N> class vector {

   private:
     boost::any elems[N];
}

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

virtual void setComp(int, float) = 0;
virtual void setComp(int, bool) = 0;
0
ответ дан 2 September 2019 в 23:33
поделиться

Прежде всего, я бы спросил себя, действительно ли вам нужен полиморфный доступ к вершинным объектам во время выполнения. Например, если вам нужно иметь список объектов vertex* с различными типами (double, int и т.д.) и иметь к ним полиморфный доступ.

Мне кажется, что вершина - это типичный случай полиморфизма во время компиляции (т.е. template class vertex; template).

0
ответ дан 2 September 2019 в 23:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: