doc*_*7b5 5 c++ arrays templates
我试图编写一个模板化的基类来存储固定数量的数据类型,每个数据类型的长度各不相同.这是我尝试做的很多简化版本:
template< int NINT, int NR0 >
class EncapsulatedObjectBase
{
   public:
  EncapsulatedObjectBase();
  ~EncapsulatedObjectBase();
  double m_real[NR0];
  int m_int[NINT];
}
是的...所以模板参数可以为零,从而声明一个零长度的对象数组.这个库将有多个派生类,每个派生类定义自己的变量数.我有两个问题:
1)这种方法是否存在根本缺陷?
2)如果是这样的话...当我实例化零长度数组时,为什么icc13或gcc4.7.2没有给我警告?对于gcc我使用-wall和-wextra -wabi.缺乏警告让我觉得这种事情还行.
编辑:
以下是显示我正在谈论的文件的内容:
#include <iostream>
template< int NINT, int NR0 >
class EncapsulatedObjectBase
{
public:
  EncapsulatedObjectBase(){}
  ~EncapsulatedObjectBase(){}
  double m_real[NR0];
  int m_int[NINT];
};
class DerivedDataObject1 : public EncapsulatedObjectBase<2,0>
{
   public:
   DerivedDataObject1(){}
  ~DerivedDataObject1(){}
  inline int& intvar1() { return this->m_int[0]; }
  inline int& intvar2() { return this->m_int[1]; }
};
class DerivedDataObject2 : public EncapsulatedObjectBase<0,2>
{
   public:
   DerivedDataObject2(){}
  ~DerivedDataObject2(){}
  inline double& realvar1() { return this->m_real[0]; }
  inline double& realvar2() { return this->m_real[1]; }
};
int main()
{
   DerivedDataObject1 obj1;
   DerivedDataObject2 obj2;
   obj1.intvar1() = 12;
   obj1.intvar2() = 5;
   obj2.realvar1() = 1.0e5;
   obj2.realvar2() = 1.0e6;
   std::cout<<"obj1.intvar1()  = "<<obj1.intvar1()<<std::endl;
   std::cout<<"obj1.intvar2()  = "<<obj1.intvar2()<<std::endl;
   std::cout<<"obj2.realvar1() = "<<obj2.realvar1()<<std::endl;
   std::cout<<"obj2.realvar2() = "<<obj2.realvar2()<<std::endl;
}
如果我用"g ++ -Wall -Wextra -Wabi main.cpp"编译它,我没有得到任何警告.我必须使用-pedantic标志来获取警告.所以我仍然不知道这是多么不安全.回想起来,我觉得它一定不是一个好主意......虽然如果我能逃脱它会非常有用.
零大小的数组在 C++ 中实际上是非法的:
\n\n\n\n\n\n
[C++11: 8.3.4/1]:[..]如果存在常量表达式(5.19),则它应为整型常量表达式,并且其值应大于零。常量表达式指定数组(元素数量)的界限。如果常量表达式的值为N,则数组的N元素编号0为N-1,且 的标识符类型为TD\xe2\x80\x9d的\xe2\x80\x9c派生声明符类型列表数组。N[..]
因此,您的类模板无法0,0 使用 GCC 4.1.2 中的参数实例化,也无法在 GCC 4.7.2 中使用合理的标志进行实例化:
template< int NINT, int NR0 >\nclass EncapsulatedObjectBase\n{\n   public:\n\n  EncapsulatedObjectBase();\n\n  ~EncapsulatedObjectBase();\n\n  double m_real[NR0];\n  int m_int[NINT];\n};\n\nint main()\n{\n   EncapsulatedObjectBase<0,0> obj;\n}\n\n\n\nt.cpp:在 \'EncapsulatedObjectBase<0, 0>\' 的实例化中:
\n
\n t.cpp:17:从此处实例化
\n 第 10 行:错误:ISO C++ 禁止零大小数组
\n 编译由于 - 终止致命错误。
铿锵 3.2 说:
\n\n\n\n\nsource.cpp:10:17:警告:零大小数组是扩展 [-Wzero-length-array]
\n
(请注意,无论如何,在尝试实例化这样的类之前,您不会收到任何错误。)
\n\n那么,这是一个好主意吗?不,不是真的。我建议当任一参数为 时,禁止类模板的实例化0。我还会了解为什么您想要零长度数组并考虑调整您的设计。