首页 > 其他分享 >Trivial, standard-layout, POD, and literal types

Trivial, standard-layout, POD, and literal types

时间:2024-09-18 11:35:27浏览次数:8  
标签:layout struct int standard literal trivial types

转自:Trivial, standard-layout, POD, and literal types

https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-layout-and-pod-types?view=msvc-170

微软这篇文章写的很详尽,也配有代码实例

Trivial, standard-layout, POD, and literal types

    The term layout refers to how the members of an object of class, struct or union type are arranged in memory. In some cases, the layout is well-defined by the language specification. But when a class or struct contains certain C++ language features such as virtual base classes, virtual functions, members with different access control, then the compiler is free to choose a layout. That layout may vary depending on what optimizations are being performed and in many cases the object might not even occupy a contiguous area of memory. For example, if a class has virtual functions, all the instances of that class might share a single virtual function table. Such types are very useful, but they also have limitations. Because the layout is undefined they cannot be passed to programs written in other languages, such as C, and because they might be non-contiguous they cannot be reliably copied with fast low-level functions such as memcopy, or serialized over a network.

    To enable compilers as well as C++ programs and metaprograms to reason about the suitability of any given type for operations that depend on a particular memory layout, C++14 introduced three categories of simple classes and structs: trivial, standard-layout, and POD or Plain Old Data. The Standard Library has the function templates is_trivial, is_standard_layout and is_pod that determine whether a given type belongs to a given category.

Trivial types

    When a class or struct in C++ has compiler-provided or explicitly defaulted special member functions, then it is a trivial type. It occupies a contiguous memory area. It can have members with different access specifiers. In C++, the compiler is free to choose how to order members in this situation. Therefore, you can memcopy such objects but you cannot reliably consume them from a C program. A trivial type T can be copied into an array of char or unsigned char, and safely copied back into a T variable. Note that because of alignment requirements, there might be padding bytes between type members.

    Trivial types have a trivial default constructor, trivial copy constructor, trivial copy assignment operator and trivial destructor. In each case, trivial means the constructor/operator/destructor is not user-provided and belongs to a class that has

  • no virtual functions or virtual base classes,

  • no base classes with a corresponding non-trivial constructor/operator/destructor

  • no data members of class type with a corresponding non-trivial constructor/operator/destructor

    The following examples show trivial types. In Trivial2, the presence of the Trivial2(int a, int b) constructor requires that you provide a default constructor. For the type to qualify as trivial, you must explicitly default that constructor.

C++

struct Trivial
{
   int i;
private:
   int j;
};

struct Trivial2
{
   int i;
   Trivial2(int a, int b) : i(a), j(b) {}
   Trivial2() = default;
private:
   int j;   // Different access control
};

Standard layout types

    When a class or struct does not contain certain C++ language features such as virtual functions which are not found in the C language, and all members have the same access control, it is a standard-layout type. It is memcopy-able and the layout is sufficiently defined that it can be consumed by C programs. Standard-layout types can have user-defined special member functions. In addition, standard layout types have these characteristics:

  • no virtual functions or virtual base classes

  • all non-static data members have the same access control

  • all non-static members of class type are standard-layout

  • any base classes are standard-layout

  • has no base classes of the same type as the first non-static data member.

  • meets one of these conditions:

  • no non-static data member in the most-derived class and no more than one base class with non-static data members, or

  • has no base classes with non-static data members

  • The following code shows one example of a standard-layout type:

C++

struct SL
{
   // All members have same access:
   int i;
   int j;
   SL(int a, int b) : i(a), j(b) {} // User-defined constructor OK
};

    The last two requirements can perhaps be better illustrated with code. In the next example, even though Base is standard-layout, Derived is not standard layout because both it (the most derived class) and Base have non-static data members:

C++


struct Base
{
   int i;
   int j;
};

// std::is_standard_layout<Derived> == false!
struct Derived : public Base
{
   int x;
   int y;
};

In this example Derived is standard-layout because Base has no non-static data members:

C++

struct Base
{
   void Foo() {}
};

// std::is_standard_layout<Derived> == true
struct Derived : public Base
{
   int x;
   int y;
};

    Derived would also be standard-layout if Base had the data members and Derived had only member functions.

POD types

    When a class or struct is both trivial and standard-layout, it is a POD (Plain Old Data) type. The memory layout of POD types is therefore contiguous and each member has a higher address than the member that was declared before it, so that byte for byte copies and binary I/O can be performed on these types. Scalar types such as int are also POD types. POD types that are classes can have only POD types as non-static data members.

Example
    The following example shows the distinctions between trivial, standard-layout, and POD types:

C++


#include <type_traits>
#include <iostream>

using namespace std;

struct B
{
protected:
   virtual void Foo() {}
};

// Neither trivial nor standard-layout
struct A : B
{
   int a;
   int b;
   void Foo() override {} // Virtual function
};

// Trivial but not standard-layout
struct C
{
   int a;
private:
   int b;   // Different access control
};

// Standard-layout but not trivial
struct D
{
   int a;
   int b;
   D() {} //User-defined constructor
};

struct POD
{
   int a;
   int b;
};

int main()
{
   cout << boolalpha;
   cout << "A is trivial is " << is_trivial<A>() << endl; // false
   cout << "A is standard-layout is " << is_standard_layout<A>() << endl;  // false

   cout << "C is trivial is " << is_trivial<C>() << endl; // true
   cout << "C is standard-layout is " << is_standard_layout<C>() << endl;  // false

   cout << "D is trivial is " << is_trivial<D>() << endl;  // false
   cout << "D is standard-layout is " << is_standard_layout<D>() << endl; // true

   cout << "POD is trivial is " << is_trivial<POD>() << endl; // true
   cout << "POD is standard-layout is " << is_standard_layout<POD>() << endl; // true

   return 0;
}

Literal types
    A literal type is one whose layout can be determined at compile time. The following are the literal types:

  • void
  • scalar types
  • references
  • Arrays of void, scalar types or references
  • A class that has a trivial destructor, and one or more constexpr constructors that are not move or copy constructors. Additionally, all its non-static data members and base classes must be literal types and not volatile.

标签:layout,struct,int,standard,literal,trivial,types
From: https://www.cnblogs.com/DesertCactus/p/18418166

相关文章

  • QStandardItem先设置图标再插入QTreeView会影响插入性能
    所有的界面显示都交代理去绘制,否则会影响插入性能;一开始打算将类型图标通过QStandardItem创建时传给QStandardItem,在插入到model中,后来发现这样会降低插入的性能;pItem=newQStandardItem(QIcon(":/foldericon.svg"),info.value("name").toString());改成用代理QStyledItemDel......
  • useEffect和useLayoutEffect的区别
    它们两个的区别主要是执行时机的不一样,要理解执行时机。首先我们来了解下浏览器的执行流程,dom树和cssom树合并为render树之后,后面的流程概括来说就是layout布局,和paint(绘制,就把最后布局好的树画在屏幕视图上)。这里直接揭晓答案,useLayoutEffect是在layout之后,paint之前执行的。而u......
  • "layout.html"代码
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><style>body{margin:0;}.pg-header{height:4......
  • Python中,使用`sklearn.preprocessing`模块中的`StandardScaler`或`MinMaxScaler`可以
    在Python中,使用`sklearn.preprocessing`模块中的`StandardScaler`或`MinMaxScaler`可以对数据进行标准化或归一化处理。以下是如何对一个列表(list)中的数据进行标准化的示例:第一结合numpy###使用StandardScaler进行标准化(Z-scorenormalization)`StandardScaler`将数据转换为均值......
  • 【Qt】表单布局QFormLayout
     表单布局QFormLayoutQt还提供了QFormLayout,属于是QGridLayout的特殊情况,专⻔⽤于实现两列表单的布局.这种表单布局多⽤于让⽤⼾填写信息的场景.左侧列为提⽰,右侧列为输⼊框例子:使用QFormLayout创建表单(1)设置三个label、三个lineEdit(2)设置表单布局,将上述......
  • Define Screen Layout at Document Level(Purchase Order): 采购订单标准屏幕字段控制
     1.维护视图:V_1622.IMG路径:输入T-code:OLME Purchasing-->PurchaseOrder-->DefineScreenLayoutatDocumentLevel 3.英文文档DefineScreenLayoutatDocumentLevelForallexternalpurchasingdocumentsandpurchaserequisitions,youcanspecifythe......
  • Android开发 - LayoutInflater 类将 XML 布局文件转换成对应的 View 对象解析
    LayoutInflater是什么LayoutInflater用于将XML布局文件转换成对应的View对象。它可以理解为一个“布局解析器”,帮助我们将静态的XML文件转换为可以动态操作的Java对象(View及其子类)LayoutInflater的主要作用在Android开发中,我们通常会在res/layout文件夹中......
  • HCL AppScan Standard 10.6.0 发布,新增功能概览
    HCLAppScanStandard10.6.0发布,新增功能概览HCLAppScanStandard10.6.0中的新增功能API扫描现在通过高级OpenAPI自动扫描改进了配置功能、增强了覆盖范围并优化了漏洞检测。AppScanConnect:支持AppScan360°:AppScanConnect现在完全支持与AppScan360°......
  • 调用Web接口产生的invalid literal for int()错误
    错误产生调用新浪股票的按节点(如hs_a)获取股票总数接口,然后转换为整型,但是返回的是字符串,导致转换失败。报invalidliteralforint()withbase10:'"5349"'错误。出错代码如下:importrequestsdefget_stock_count(node='hs_a'):url=f'https://vip.stock.......
  • 讨论TableLayoutPanel加载缓慢和闪烁问题解决方案
    WinForm加载多个自定义控件时,会出现很严重的闪烁问题,很卡,一块一块的加载(像打开网页时,网络很卡的那种感觉)简直没法忍受。在网上搜索了好久,网上大部分的方法是一下4种,但是都不能有效的解决问题。1、将DoubleBuffered设置true,用双缓存处理Form界面内容加载,可以提高页面显......