如果T是POD,std :: array <T,S>是否保证为POD?

Rap*_*tor 17 c++ templates stl tr1 c++11

我正在编写一个C++内存编辑库,对于读/写API,我使用类型特征(std :: is_pod,std :: is_same)和boost :: enable_if来提供3个重载:

  1. POD类型.例如MyMem.Read(SomeAddress);
  2. 字符串类型.例如MyMem.Read>(SomeAddress); (这实际上并没有读出C++字符串,它会读出一个C风格的字符串并将其转换为C++字符串.)
  3. 矢量类型.例如MyMem.Read>(SomeAddress,NumElem); (这实际上并没有读出一个向量,而是读出一个C风格的数组并将其转换为向量.)

重载2和3只是在重载1周围的'包装器'.(因此,如果你正在读取std :: vector或std :: basic_string而T不是POD,它将失败,因为它应该.)

最近我想使用std :: array进行一堆读写操作,因为我知道我想在编译时读写的数据大小(我正在编写一个围绕PE文件格式的包装器).

我编写了使用std :: array的代码,然后打算为std :: array类型的检测和处理添加另一个重载,但是我不小心遇到了编译,令我惊讶的是它工作了!

我目前正在使用MSVC 10,事实证明,对于std :: array,如果T是POD,则std :: array是POD.(这意味着我可以使用重载1并且它可以工作.)

我的问题是这是由C++标准保证还是由实现完成.

我知道我可以自己检查标准,但我不相信自己,因为我相信这个网站上的一些语言律师,所以我认为最好得到"第二意见".;)

谢谢

此处提供的PS代码(它是一个仅限标题的lib):http: //code.google.com/p/hadesmem/source/browse/trunk/HadesMem-v2/Hades-Memory/Hades-Memory/MemoryMgr.h#86

Pot*_*ter 12

§23.3.1:

数组是一个聚合(8.5.1),可以用语法初始化,array a<T, N> = { initializer-list }; 其中initializer-list是一个逗号分隔的列表,最多包含N个元素,其类型可以转换为T.

在C++ 03中,POD是根据聚合定义的:一个类,其中每个子对象都是本机的,或者聚合是POD.因此,通过向后兼容性,C++ 0x std::array是POD.

或者,要肛门,可以比较§9/ 5(定义普通类)9/6(定义标准布局)和9/9(将先前要求与POD相结合)与8.5.1/1,定义聚合.

8.5.1:

聚合是一个数组或类(第9节),没有用户提供的构造函数(12.1),非静态数据成员(9.2)没有大括号或相等的初始值,没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3).

实际上array,只要其元素类型也是POD并且除了规范之外没有声明operator=move内部实现,第9条中的要求也包括在内array.

真正肛门,17.5.2.2说

  1. 为了便于说明,第18至30条和附件D没有描述复制/移动构造函数,赋值运算符或(非虚拟)析构函数,它们具有与默认生成的语义相同的明显语义(12.1,12.4,12.8) ).
  2. 未指定实现是否为此类成员函数签名提供显式定义,或者是否为默认情况下生成的虚拟析构函数提供了明确定义.

伪代码中的注释template class array

// No explicit construct/copy/destroy for aggregate type

construct/copy/destroy包括operator=(分配)或move?它可能应该,但我不认为,通过最严格的阅读,它确实如此.

请注意,这不仅会"影响"POD,而且会影响Johannes提到的琐碎可复制性.

  • 呸,标准中这些细长的表述......为什么他们不能在委员会中写下东西:( (2认同)

dir*_*tly 7

根据POD的定义:

9个课程

9 POD结构是一个既简单类又是标准布局类的类,并且没有非POD结构类型的非静态数据成员,非POD联合(或此类类型的数组).类似地,POD联合是一个简单类和标准布局类的联合,并且没有非POD结构类型的非静态数据成员,非POD联合(或这种类型的数组).POD类是POD结构或POD联合的类.

[强调我的]

std::array确实满足了作为一个简单的标准布局类模板的所有要求.所以你的问题的答案是肯定的.