C++之std::is_pod

概述

        POD(Plain old data), 平凡的数据, 也是旧 C 语言中的那些类型。 POD 类型还包括标量类型。 POD 类类型是既平凡(可以静态初始化)trivial和标准布局Standard layout(这是一个简单的数据结构,如结构和联合)的类类型。

        std::is_pod的原型:template is_pod;

        模板只能有类型 T 的参数,并检查给定的类型是否为普通旧数据类型,它返回一个布尔值,如果给定类型是普通旧数据,则返回 true,如果给定类型不是普通旧数据,则返回 false。

C++基础回顾

1、 C++定义一个类 class CTest{}; 系统编译器会默认生成的函数有:

            1)默认构造函数,没有参数

            2)拷贝构造函数

            3)拷贝赋值操作符

            4)  默认析构函数

            5)移动构造函数

            6)移动赋值操作符

2、当自定义类型时,如果编码实现了任意一个构造函数,则编译器将不会自动合成默认构造函数。C++11中可使用=default显示声明默认构造函数,加了关键字=default生成的构造函数和默认构造函数是一个效果

3、当自定义类型时,如果需要限制类的某些构造函数调用,在C++11中可使用=delete来阻止用户的调用

Trivial 类型

极简 (trivial),可以通过std::is_trivial::value判断,判断trivial的条件是:

  • 有平凡的构造函数
  • 有平凡的拷贝构造函数
  • 有平凡的移动构造函数
  • 有平凡的拷贝赋值运算符
  • 有平凡的移动赋值运算符
  • 有平凡的析构函数
  • 不能包含虚函数
  • 不能包含虚基类
  • 成员变量及基类也要满足上述条件

判断下面定义的几个struct是否是trivial类型:

class MyTest1{
    int m1;
};

class MyTest2{
public:
    MyTest2(double val):m1(val){}
private:
    double m1;
};

class MyTest3{
public:
    MyTest2(int val = 0):n(val){}
private:
    int n;
};

class MyTest4{
public:
    MyTest4(){}
    MyTest4(int val):n(val){}
private:
    int n;
};

class MyTest5{
public:
    MyTest5() = default;
    MyTest5(int val):n(val){}
private:
    int n;
};

class MyTest6{
public:
    MyTest6() = default;
    MyTest6(MyTest6&& val);
private:
    MyTest6* m_pTest;
};

printf("is_trivial:%d\n", std::is_trivial::value);// true
printf("is_trivial:%d\n", std::is_trivial::value);// false
printf("is_trivial:%d\n", std::is_trivial::value);// false
printf("is_trivial:%d\n", std::is_trivial::value);// false
printf("is_trivial:%d\n", std::is_trivial::value);// true
printf("is_trivial:%d\n", std::is_trivial::value);// false

标准布局 (standard layout)

标准布局 (standard layout),可以通过std::is_standard_layout::value判断,满足标准布局的条件有:

  • 所有非静态成员有相同的访问权限
  • 继承树中最多只能有一个类有非静态数据成员
  • 子类的第一个非静态成员不可以是基类类型
  • 没有虚函数
  • 没有虚基类
  • 所有非静态成员都符合标准布局类型
struct S1{
    int i;
};

struct B1{
    void foo(){}
};
struct S2 : public B1{
    int i;
};

struct B2{
    int n;
};
struct S3 : public B2{};

struct S4 : public B2{
    int i;
};

struct S5 : public B1{
    B1 b;
    int m;
};

struct S6 : public B1{
    int m;
    B1 b;
};

struct S7 : virtual public B1{};

struct S8{
    S8(int val):mVal(val){}
private :
    int mVal;
};

// Trivial but not standard-layout
struct S9{
public:
    int m;
private:
    int n;
};

printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// false

printf("\n\n");
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true
printf("is_standard_layout:%d\n", std::is_standard_layout::value);// true

总结

POD 类 是满足以下所有条件的类:

  • 它是聚合体,
  • 没有用户声明的复制赋值运算符,
  • 没有用户声明的析构函数,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 前)
  • 它是平凡类,
  • 它是标准布局类,并且
  • 没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
(C++11 起)


POD 结构体 是非联合体的 POD 类。POD 联合体 是满足 POD 类条件的联合体。

POD 属性的使用被弃用。用户代码应该期待或要求平凡或标准布局属性,或者它们两者。

(C++20 起)

你可能感兴趣的:(#C++,linux,运维,服务器)