平凡,标准布局,POD


77

用外行的话来说,平凡类型,标准布局类型和POD有什么区别?

具体来说,我想确定是否new Tnew T()任何模板参数不同T。哪种类型的性状is_trivialis_standard_layout而且is_pod我应该选择?

(作为附带的问题,这些类型特征中的任何一种都可以在没有编译器魔术的情况下实现吗?)


3
我认为提这个有点迟。但是对于那些希望获得详细阐述的答案的人,这里是链接。检查R Martinho Fernandes的回答stackoverflow.com/questions/4178175/…–
jmishra 2012年

Answers:


67

我认为,至少在没有大量额外解释的情况下,这不是真正意义上的外行人可以做到的。重要的一点是静态初始化与动态初始化,但是向外行解释,其本身将是几页...

POD在(C ++)98中定义。确实有两个单独的意图,它们都没有很好地表达:1)如果您在C ++中编译C struct声明,则所获得的内容应等同于C中的内容。2)POD仅会需要/使用静态(非动态)初始化。

C ++ 0x / 11(几乎)完全放弃了“ POD”标记,而赞成“琐碎的”和“标准布局”。标准布局旨在捕获第一个意图-使用与C语言中相同的布局创建某些内容。Trivial旨在捕获对静态初始化的支持。

由于new Tvs.new T()负责初始化,因此您可能需要is_trivial

我不确定是否需要编译器魔术。我的即时反应可能是肯定的,但是了解人们使用TMP所做的一些事情后,我很难确定某人也无法做到这一点...

编辑:例如,也许最好引用N3290的示例:

struct N { // neither trivial nor standard-layout
   int i;
   int j;
    virtual ~N();
};

struct T { // trivial but not standard-layout
    int i;
private:
    int j;
};

struct SL { // standard-layout but not trivial
    int i;
    int j;
    ~SL();
};

struct POD { // both trivial and standard-layout
    int i;
    int j;
};

无疑,POD这也是POD结构。


1
所以trivial + standard layout = POD总是成立吗?
fredoverflow 2011年

1
@FredOverflow:是的,前提是它是可传递的,所以所有(非静态)成员都必须是平凡的+标准布局。
杰里·科芬,

@JerryCoffin可能值得一提的是简单类型的连续内存布局,因为这是一个非常重要的属性
awdz9nld


0

布局是类,结构或联合的对象的成员在内存中的排列方式。这可能是不连续的。语言经常指定布局,但是如果存在诸如虚函数,虚拟基类等内容,那么编译器可以自由选择布局,而这可能不是连续的。这导致了一些问题,我们无法适当地序列化对象或将其传递给使用其他语言(如C)或函数(如memcopy)编写的程序,因为我们无法可靠地复制不在相邻位置的数据。

为了使编译器和c ++程序能够支持上述操作,c ++为简单的结构和类引入了3类。

不重要的

如果一个类或结构遵循以下规则,则它是微不足道的:

  • 没有虚函数或虚基类
  • 没有用户定义的构造函数/运算符/析构函数
  • 基类应该是微不足道的
  • 所有班级成员都应该是琐碎的

如果一个类是琐碎的,则其布局是连续的,但可能会有相应的填充,并且编译器可以自由选择布局中成员的顺序。因此,即使我们可以复制对象,如果将对象复制到C程序中也不可靠。我们可以在同一个类中拥有不同的访问说明符,并且如果使用参数化构造函数,则显然必须指定默认构造函数。但是,如果您想让该类变得微不足道,则应显式将构造函数设为默认值。构造函数应为public。

标准版式

  • 没有虚拟功能和虚拟基类
  • 所有非静态成员应具有相同的访问说明符
  • 所有非静态成员均应采用标准布局
  • 所有基类均应采用标准布局
  • 基类的所有成员都应该是静态的
  • 基类的类型和该类的第一个非静态成员应该不相同

标准布局定义明确,可以可靠地复制并适当地传递给C程序。同样,标准布局功能可以具有用户定义的特殊成员功能,例如构造函数和析构函数。

POD(普通旧数据)

如果一个类或结构既是普通布局又是标准布局,则称其为POD。每个成员均按声明对象时指定的顺序存储。POD类应具有POD非静态数据成员.POD类可以可靠地复制或传递给C程序。

C ++程序的类很小,是标准布局,因此是POD。

#include<iostream>
#include<type_traits>
class xyz
{
public:
    int a;
    int b;
    xyz() = default;
    xyz(int x, int y) :a(x), b(y) {}
};
int main() {
    std::cout << std::is_trivial<xyz>() << std::endl;//true
    std::cout << std::is_standard_layout<xyz>() << std::endl;//true
    std::cout << std::is_pod<xyz>() << std::endl;//true
}

文字类型

对于文字类型,可以在编译时确定布局。文字类型的示例为void,标量类型(如int,float等),引用,void的数组,标量类型或引用以及具有琐碎析构函数的类,以及不是移动或复制构造函数的一个或多个constexpr构造函数。此外,其所有非静态数据成员和基类必须是文字类型,并且不是易变的


它几乎来自docs.microsoft.com/en-us/cpp/cpp/…,仅粘贴URL会更容易吗?
r0ng
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.