c++ - 大小由模板参数定义的成员数组,但为什么没有对零大小数组发出警告?

标签 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++ 中实际上是非法的:

[C++11: 8.3.4/1]: [..] If the constant-expression (5.19) is present, it shall be an integral constant expression and its value shall be greater than zero. The constant expression specifies the bound of (number of elements in) the array. If the value of the constant expression is N, the array has N elements numbered 0 to N-1, and the type of the identifier of D is “derived-declarator-type-list array of N T”. [..]

因此,您的类模板不能用参数0,0 实例化in GCC 4.1.2也不in GCC 4.7.2带有合理的标志:

template< int NINT, int NR0 >
class EncapsulatedObjectBase
{
   public:

  EncapsulatedObjectBase();

  ~EncapsulatedObjectBase();

  double m_real[NR0];
  int m_int[NINT];
};

int main()
{
   EncapsulatedObjectBase<0,0> obj;
}

t.cpp: In instantiation of 'EncapsulatedObjectBase<0, 0>':
t.cpp:17: instantiated from here
Line 10: error: ISO C++ forbids zero-size array
compilation terminated due to -Wfatal-errors.

clang 3.2 说:

source.cpp:10:17: warning: zero size arrays are an extension [-Wzero-length-array]

(请注意,在任何情况下,除非您尝试实例化此类,否则不会出现任何错误。)

那么,这是个好主意吗?不,不是真的。当任一参数为 0 时,我建议禁止实例化您的类模板。我还会了解为什么您想要零长度数组并考虑调整您的设计。

关于c++ - 大小由模板参数定义的成员数组,但为什么没有对零大小数组发出警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14390822/

相关文章:

c++ - 如何在函数返回之前将新大小的数组从 C++ DLL 发送到 Delphi

arrays - 有没有办法在 Bash 中将一个字符串数组拆分为多个其他数组?

c++ - 重载 > 运算符以识别包含字符串的节点

c++ - x86 汇编中的 "lock"指令是什么意思?

C++ 对象和线程

C++将参数中的函数传递给另一个函数

arrays - 是否可以在 Swift 中创建一个仅限于一个类的数组扩展?

Javascript:以数组名称的一部分作为参数的函数?

c++ - 根据不同的类型在运行时实例化一个模板类

c++ - 模板模板参数的模板特化