2011-09-24 76 views
4

C++ 11标准保证字节对每个字节的副本始终对POD类型有效。但是,某些微不足道的类型呢?C++ 11中字节对字节的类型拷贝?

下面是一个例子:

struct trivial 
{ 
    int x; 
    int y; 
    trivial(int i) : x(2 * i) { std::cout << "Constructed." << std::endl; } 
}; 

如果我要复制这个结构,字节对字节,是保证正确复制,即使它在技术上不是POD?什么时候画的线是而不是好的字节复制对象?

+1

相关:http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821 –

回答

9

是的,它是保证复制正确。

引述FDIS,§3.9/ 2:

对于平凡复制的类型T的任何对象(比基类的其他子对象)时,对象是否保持类型的有效值T,组成对象的基础字节可以被复制到charunsigned char的数组中。如果将charunsigned char的数组内容复制回对象中,则该对象将随后保持其原始值。

和§3.9/ 3:

对于任何平凡复制的类型T,如果两个指针T指向不同T对象obj1obj2,其中既不obj1也不obj2是一个碱基如果构成obj1的基础字节被复制到obj2中,则obj2将随后保持与obj1相同的值。

所以你问的要求是,§3.9/ 9:

运算类型,枚举类型,指针类型,指针成员类型,std::nullptr_t,而这些CV-合格版本类型统称为标量类型。标量类型,POD类,这类类型的数组和cv-qualified这些类型的版本统称为POD类型标量类型,可简单复制的类类型,此类类型的数组以及这些类型的cv限定版本统称为可微复制类型

而且§9/ 6:

平凡能够复制类是一个类:

  • 没有非平凡的拷贝构造函数,
  • 没有非琐碎的移动构造函数,
  • 没有非平凡的复制赋值运算符,
  • 没有不平凡的移动赋值操作符,并且
  • 有一个微不足道的析构函数。
+4

trivial :: trivial(int)'不是默认或复制构造函数。因此,它并不真正影响“微不足道”的复制琐事。 – MSN

+1

MSN说的很重要,因为回到C++ 03,构造函数会影响POD性。所以C++ 11允许这样做,而C++ 03则没有。 –

3

如果标准规定它只是为POD类型定义的(我还没有仔细检查过C++ 11标准,所以我不知道你的争用是否正确(a))和你做一个非POD类型,它没有定义的行为。期。

在一些实现中,在行星对齐时的某些环境中,它可能在一天中的某些时间工作。它可能工作绝大多数时候。如果你重视可移植性,那么这仍然不是一个好主意。


(一)更多的调查后,它将显示你的具体情况是好的。该标准的第3.9/3(n3242 draft,但我会感到惊讶,如果它已经从这么晚草案太大的改变)指出:

对于任何平凡复制的类型T,如果两个指针至T点不同ŧ对象obj1和obj2其中,obj1和obj2都不是基类子对象,如果组成obj1的基础字节被复制到obj2中,则obj2将随后保持与obj1相同的值。

第九节定义(在高电平)什么是“平凡能够复制”是指:

甲平凡能够复制类是一类:
- 不具有非平凡复制构造(12.8) ,
- 没有非平凡的举动构造函数(12.8),
- 没有非平凡的拷贝赋值运算符(13.5.3,12.8),
- 没有非平凡的举动赋值运算符(13.5.3, 12.8)和
- 有一个微不足道的析构函数(12.4)。

与引用的部分进入更详细地在每个区域中,12.8用于复制和分配用于移动类对象和13.5.3

+0

-1他的类型是“平凡的可复制的“,这是C++ 11中用于从其值表示重建对象的唯一要求。 – ildjarn

+0

@ildjarn:因此在开始的“如果”。 – paxdiablo

+0

所以你的答案是“如果你说的话是真的那么它是非法的,但我不知道你说的话是否属实”?这个答案如何? – ildjarn

4

C++ 11打破了POD类型的定义成更有用的类别,具体“琐碎”和“标准布局”。你的例子是标准布局,并且可以复制,尽管构造函数可以防止它变得微不足道。平凡能够复制类型保证是安全地逐字节复制:

对于任何对象平凡 能够复制类型T的(比基类子对象等),对象是否保持 类型的有效值T,构成对象的基础字节(1.7)可以被复制到一个char或unsigned char的数组中.40如果char或unsigned char的数组的内容被复制回到对象中,则对象应该随后 保持其原始价值。

因此,不需要POD状态以这种方式安全复制,但可以识别非POD类型的子集。