шаблонная переменная - PullRequest
       1

шаблонная переменная

5 голосов
/ 22 сентября 2011

В настоящее время у меня есть следующий не шаблонный код:

class Vector{ 
  public:
    double data[3];
 };
static Vector *myVariable;
void func() {
  myVariable->data[0] = 0.;
}
int main() {
  myVariable = new Vector();
  func();
}

Затем я хочу создать шаблон для измерения:

template<int DIM> class Vector{ 
  public:
    double data[DIM];
 };
static Vector<3>* myVariable;
void func() {
  myVariable->data[0] = 0.;
}
int main() {
  myVariable = new Vector<3>();
  func();
}

Но я, наконец, хочу также шаблонизировать мою переменную с размером:

template<int DIM> class Vector{ 
  public:
    double data[DIM];
 };
template<int DIM> static Vector<DIM> *myVariable;

void func() {
  myVariable->data[0] = 0.;
  // or perform any other operation on myVariable
}
int main() {
  int dim = 3; 

  if (dim==3)
    myVariable = new Vector<3>();
  else
    myVariable = new Vector<4>();

  func();
}

Однако эта последняя версия кода выдает ошибку: эта статическая переменная не может быть шаблонизирована («C2998: Vector * myVariable не может быть определением шаблона»).

Как можно исправить эту ошибку без полной редизайна (например, наследовать шаблонный класс Vector от не шаблонного класса, что потребовало бы более дорогих вызовов виртуальных методов, или вручную создать несколько переменных myVariables разных измерений)? Может быть, я просто устал и не вижу очевидного ответа: s

Редактировать: обратите внимание, что этот код является минимальным рабочим кодом для отображения ошибки, но моя фактическая реализация использует шаблоны для класса полной вычислительной геометрии, поэтому я не могу просто заменить Vector на массив. Я вижу, что, похоже, нет решения моей проблемы.

Спасибо!

Ответы [ 5 ]

2 голосов
/ 22 сентября 2011

Это было давно, но я раньше использовал константы в объявлении шаблона. В конце концов я пошел в другом направлении с тем, над чем я работал, поэтому я не знаю, будет ли это в конечном итоге и вашим решением. Я думаю, что проблема здесь в том, что любая шаблонная переменная должна знать свой аргумент шаблона в время компиляции .

В вашем примере Vector<3> и Vector<4> - это разные типы, и их нельзя назначить одной и той же переменной. Вот почему template<int DIM> static Vector<DIM> *myVariable не имеет никакого смысла; у него нет различимого типа.

1 голос
/ 22 сентября 2011
template<int DIM> static Vector<DIM> *myVariable;

Это не разрешено спецификацией языка. Конец истории.

И поскольку я не понимаю цели вашего кода или того, чего вы хотите достичь, я не могу предложить лучшую альтернативу, чем просто , предлагая вам попробовать использовать std::vector<T>. Это также потому, что я не знаю, сколько мне позволено изменить ваш код и то, как вы его используете, чтобы ваш код работал.

0 голосов
/ 23 сентября 2011

Vector<3> и Vector<4> являются полностью различными типами и имеют нет формального отношения друг к другу. Тот факт, что они внешне похожи с вашей точки зрения, не имеет значения.

Если вы хотите, чтобы они были эквивалентны до определенного типа, у нас есть имя для этого: interfaces

template <typename Scalar = float>
class BasicVector {
public:
    typedef Scalar * iterator;
    virtual ~ BasicVector () {}

    virtual size_t   size  () const = 0;
    virtual iterator begin ()       = 0;
    virtual iterator end   ()       = 0;
};

template <unsigned N, typename Scalar = float>
class Vector : public BasicVector <Scalar> {
    Scalar m_elements [N];
public:
    using Scalar :: iterator;
    size_t   size  () const {return N;}
    iterator begin ()       {return m_elements;}
    iterator end   ()       {return m_elements + N;}
};

int main () {
    BasicVector * a;
    a = new Vector <3>;
    a = new Vector <4>;
}
0 голосов
/ 22 сентября 2011

Кажется, я нашел!

template<int DIM> class Vector{ 
  public:
    double data[DIM];
 };
static void *myVariable;

template<int DIM>
void func() {
((Vector<DIM>*)myVariable)->data[0] = 0.;
  // or perform any other operation on myVariable
}
int main() {
  int dim = 3; 

  if (dim==3)
  {
    myVariable = (void*) new Vector<3>();
    func<3>();
  }
  else
  {
    myVariable = (void*) new Vector<4>();
    func<4>();
   }


}
0 голосов
/ 22 сентября 2011

Вы можете использовать std::array для шаблонизации размера, но вы не можете привести указатель одного измерения к указателю другого.

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