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

Мой основной класс проекта - это шаблонный класс, объявленный с помощью:

template<int dim, typename typ>

где dim — количество измерений (2 или 3), а typ — тип данных с плавающей запятой (float или double). Основываясь на этих параметрах, экземпляры этого класса имеют члены определенного типа, а векторы (математика) имеют небольшое количество компонентов.

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


person Fic Firic    schedule 30.07.2010    source источник
comment
В чем проблема? Можете ли вы привести примеры того, как вы предполагаете называть эти объекты? Я подозреваю, что вам не нужен метод @Tyler McHenry (это правильно, просто может быть излишним). Я предлагаю определить класс с методами и элементами, которые вам нужны, и вернуться к нам, когда у вас будет что-то, что не будет компилироваться :-) template‹int dim, typename typ› struct X { void f(typ t); };   -  person Aaron McDaid    schedule 31.07.2010


Ответы (1)


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

class Base {

  public:

    virtual ~Base() {};

    virtual void foo() = 0;

    virtual int bar(int param) = 0; 

    // Etc, for whatever other methods you want
};

Затем вы получаете свой шаблон от него:

template<int dim, typename typ>
class Dervied : public Base
{
  public:

    virtual ~Derived();

    virtual void foo();

    virtual int bar(int param); 

    // Etc, for whatever other methods you want   

  private:

    std::vector<typ> data;
};

И, конечно же, реализуйте методы для шаблона Derived. Затем вы можете получить доступ к любому экземпляру Derived через указатель или ссылку на Base. Например:

void callFoo(const Base& b)
{
   b.foo();
}

int main() 
{
  Derived<3,float> d_f3;
  Derived<2,double> d_d2;

  callFoo(d_f3);
  callFoo(d_d2);

  return 0;
}

Судя по вашему описанию, могут быть некоторые методы, общие для всех экземпляров Derived, но некоторые из них зависят от параметров шаблона, например.

void addNumber(typ number);

В этом случае вы не можете вытащить эту функцию в Base, так как не имеет смысла вызывать этот метод на Derived<n,float>. Если есть некоторые функции, которые зависят от типа, а некоторые зависят от числа, то вы можете создать базовые классы, инкапсулирующие эти идеи, например:

class Base 
  { /* All methods independent of template parameters */ };

template <int dim> DimBase : virtual public Base
  { /* All methods dependent only on the dimension parameter */ };

template <typename typ> TypBase : virtual public Base
  { /* All methods dependent only on the type parameter */ };

template<int dim, typename typ>
  Derived : public DimBase<dim>, public TypBase<typ>
  { /* All methods */ };

Это позволит вам вызывать любой независимый метод, используя указатель или ссылку Base, вызывать любой метод, зависящий от измерения, используя указатель или ссылку DimBase<n>, и любой метод, зависящий от типа, используя указатель или ссылку TypBase<T>.

Обратите внимание, что в приведенном выше примере рекомендуется, чтобы Base, TypBase и DimBase были абстрактными классами (содержащими хотя бы один нереализованный виртуальный метод), и важно, чтобы TypBase и DimBase наследуются от Base, используя вместо этого virtual public. всего public, иначе вы получите "ужасный бриллиант< /а>"

person Tyler McHenry    schedule 30.07.2010
comment
Тайлер спасибо за ответ. Простое наследование не является проблемой, самая большая проблема, с которой я сталкиваюсь, это параметры функции, которые зависят от размера и типа, например. vec‹дим,тип›. Что насчет них ? - person Fic Firic; 31.07.2010
comment
Вторая часть моего ответа касается того, как вы можете получить полиморфное поведение для методов, которые зависят либо от измерения, либо от типа. Методы, которые зависят как от и измерения, так и от типа, должны быть определены в конечном классе и не могут использоваться полиморфно. Подумайте об этом: если аргументы метода зависят как от размерности, так и от типа класса, как вы могли бы ожидать вызова того же метода для объекта класса с другой размерностью и типом? Такая вещь не имела бы никакого смысла. - person Tyler McHenry; 31.07.2010