模板变量

时间:2011-09-22 16:52:54

标签: c++ templates

我目前有以下非模板化代码:

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 个答案:

答案 0 :(得分:2)

已经有一段时间了,但我之前在模板声明中使用了常量。我最终还是按照我的工作方向转向另一个方向,所以我不知道它是否最终也是你的解决方案。我认为这里的问题是任何模板化变量必须在编译时知道它的模板参数。

在您的示例中,Vector<3>Vector<4>是不同的类型,无法分配给同一个变量。这就是template<int DIM> static Vector<DIM> *myVariable没有任何意义的原因;它没有可识别的类型。

答案 1 :(得分:1)

template<int DIM> static Vector<DIM> *myVariable;

语言规范不允许这样做。故事的结尾。

由于我不了解您的代码的目的,或者您想要实现的目标,我不能建议任何更好的选择,而不仅仅是建议尝试使用 std::vector<T>。这也是因为我不知道我有多少重新设计您的代码,以及您使用它的方式,以使代码工作。

答案 2 :(得分:0)

您可以使用std::array模板化尺寸,但无法将一个尺寸的指针投射到另一个尺寸的指针上。

答案 3 :(得分:0)

我想我找到了!

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>();
   }


}

答案 4 :(得分:0)

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>;
}