C ++ cold knowledge (b) - determining the type of performance optimization

This version introduces C ++ keywords are two leading underscores, therefore, is not very familiar with it is not recommended, mainly for internal use standard library.

table of Contents

1、__is_trivial

2、__is_trivially_copyable

3、__is_standard_layout

4、__is_pod

5、__is_literal_type

6、__is_empty

7、__is_polymorphic

8、__is_constructible

9、__is_trivially_constructible

10、__is_assignable

11、__is_trivially_assignable

12、__has_trivial_destructor

13、__has_virtual_destructor

14、__is_base_of

15、__is_final

16、__is_abstract

17、__underlying_type

18、__is_aggregate

19、__has_unique_object_representations


1、__is_trivial

Function: determining whether a class trivial class
condition (satisfy):
1, no custom constructor (but can be customized with a default modified non-argument constructor)
2, no assignment operator function
3, no virtual functions
4, no virtual base class

example:

#include <iostream>

struct A { };
struct B
{
    B() = default;
};
struct C
{
    C operator=(const C &) { }
};
struct D
{
    virtual void func() { }
};
struct E : public virtual A { };
struct F
{
    void func() { }
};
struct G
{
    G(const G &) = default;
};
struct H
{
    H(const H &) { }
};
struct I
{
    I(I &&) { }
};
struct J
{
    J() { }
};
int main()
{
    std::cout << std::boolalpha;
    std::cout << "A is __is_trivial: " << __is_trivial(A) << std::endl;
    std::cout << "B is __is_trivial: " << __is_trivial(B) << std::endl;
    std::cout << "C is __is_trivial: " << __is_trivial(C) << std::endl;
    std::cout << "D is __is_trivial: " << __is_trivial(D) << std::endl;
    std::cout << "E is __is_trivial: " << __is_trivial(E) << std::endl;
    std::cout << "F is __is_trivial: " << __is_trivial(F) << std::endl;
    std::cout << "G is __is_trivial: " << __is_trivial(G) << std::endl;
    std::cout << "H is __is_trivial: " << __is_trivial(H) << std::endl;
    std::cout << "I is __is_trivial: " << __is_trivial(I) << std::endl;
    std::cout << "J is __is_trivial: " << __is_trivial(J) << std::endl;
    return 0;
}

operation result:

2、__is_trivially_copyable

Function: Analyzing ordinary class is a class reproducible
conditions (satisfy):
1, no explicit no argument constructor
2, no custom copy constructor (but can be customized with a default modified copy constructors)
3 no moving constructor
4, no assignment operator function
5, no virtual functions
6, non-virtual base class

example:

#include <iostream>

struct A { };
struct B
{
    B() = default;
};
struct C
{
    C operator=(const C &) { }
};
struct D
{
    virtual void func() { }
};
struct E : public virtual A { };
struct F
{
    void func() { }
};
struct G
{
    G(const G &) = default;
};
struct H
{
    H(const H &) { }
};
struct I
{
    I(I &&) { }
};
struct J
{
    J() { }
};
int main()
{
    std::cout << std::boolalpha;
    std::cout << "A is __is_trivially_copyable: " << __is_trivially_copyable(A) << std::endl;
    std::cout << "B is __is_trivially_copyable: " << __is_trivially_copyable(B) << std::endl;
    std::cout << "C is __is_trivially_copyable: " << __is_trivially_copyable(C) << std::endl;
    std::cout << "D is __is_trivially_copyable: " << __is_trivially_copyable(D) << std::endl;
    std::cout << "E is __is_trivially_copyable: " << __is_trivially_copyable(E) << std::endl;
    std::cout << "F is __is_trivially_copyable: " << __is_trivially_copyable(F) << std::endl;
    std::cout << "G is __is_trivially_copyable: " << __is_trivially_copyable(G) << std::endl;
    std::cout << "H is __is_trivially_copyable: " << __is_trivially_copyable(H) << std::endl;
    std::cout << "I is __is_trivially_copyable: " << __is_trivially_copyable(I) << std::endl;
    std::cout << "J is __is_trivially_copyable: " << __is_trivially_copyable(J) << std::endl;
    return 0;
}

operation result:

3、__is_standard_layout

Function: determining whether a class is a standard layout type
conditions (satisfy):
1, all non-static members have the same access rights
2, (derived classes without non-static member, and at most a base class has a non-static data members) or ( no non-static base class data members)
3, a first class in a different type of non-static member base type
4, are all non-standard layout of the static members, a base class standard layouts
5, no virtual functions
6 no virtual base class

example:

#include <iostream>

struct A { };
struct B
{
    double arg1;
    int arg2;
    float arg3;
};
struct C
{
private:
    double arg1;
public:
    int arg2;
    float arg3;
};
struct D
{
    double arg1;
    int arg2;
    float arg3;

    double func() { return arg1; }
};
struct E
{
    double arg1;
    int arg2;
    float arg3;

    virtual double func() { return arg1; }
};
struct F : C  { };
struct G : B  { };
struct H : A
{
    static int arg;
};
struct I : B
{
    int value;
};
struct J : H
{
    static int value;
};
struct K : A
{
    A a;
};
int main()
{
    std::cout << std::boolalpha;
    std::cout << "A is __is_standard_layout: " << __is_standard_layout(A) << std::endl;
    std::cout << "B is __is_standard_layout: " << __is_standard_layout(B) << std::endl;
    std::cout << "C is __is_standard_layout: " << __is_standard_layout(C) << std::endl;
    std::cout << "D is __is_standard_layout: " << __is_standard_layout(D) << std::endl;
    std::cout << "E is __is_standard_layout: " << __is_standard_layout(E) << std::endl;
    std::cout << "F is __is_standard_layout: " << __is_standard_layout(F) << std::endl;
    std::cout << "G is __is_standard_layout: " << __is_standard_layout(G) << std::endl;
    std::cout << "H is __is_standard_layout: " << __is_standard_layout(H) << std::endl;
    std::cout << "I is __is_standard_layout: " << __is_standard_layout(I) << std::endl;
    std::cout << "J is __is_standard_layout: " << __is_standard_layout(J) << std::endl;
    std::cout << "K is __is_standard_layout: " << __is_standard_layout(K) << std::endl;
    return 0;
}

operation result:

4、__is_pod

Function: determining whether the type is a plain old data type (i.e., type C language support)
conditions (satisfy):
1, such as the ordinary type
2, such as the standard layout type

example:

#include <iostream>

struct A { };
struct B
{
    double arg1;
    int arg2;
    float arg3;
};
struct C
{
private:
    double arg1;
public:
    int arg2;
    float arg3;
};
struct D
{
    double arg1;
    int arg2;
    float arg3;

    double func() { return arg1; }
};
struct E
{
    double arg1;
    int arg2;
    float arg3;

    virtual double func() { return arg1; }
};
struct F : C  { };
struct G : B  { };
struct H : A
{
    static int arg;
};
struct I : B
{
    int value;
};
struct J : H
{
    static int value;
};
struct K : A
{
    A a;
};
struct L : B
{
    L() { }
};
int main()
{
    std::cout << std::boolalpha;
    std::cout << "A is __is_pod: " << __is_pod(A) << std::endl;
    std::cout << "B is __is_pod: " << __is_pod(B) << std::endl;
    std::cout << "C is __is_pod: " << __is_pod(C) << std::endl;
    std::cout << "D is __is_pod: " << __is_pod(D) << std::endl;
    std::cout << "E is __is_pod: " << __is_pod(E) << std::endl;
    std::cout << "F is __is_pod: " << __is_pod(F) << std::endl;
    std::cout << "G is __is_pod: " << __is_pod(G) << std::endl;
    std::cout << "H is __is_pod: " << __is_pod(H) << std::endl;
    std::cout << "I is __is_pod: " << __is_pod(I) << std::endl;
    std::cout << "J is __is_pod: " << __is_pod(J) << std::endl;
    std::cout << "K is __is_pod: " << __is_pod(K) << std::endl;
    std::cout << "L is __is_pod: " << __is_pod(L) << std::endl;
    return 0;
}

operation result:


 

Since a little more than the type of example that later supplemented to come back, now only listed.

5、__is_literal_type

功能:判断一个类型是否是字面类型
条件(满足任意):
1、该类为标量类型(即int、double等基本数据类型)
2、该类为引用类型
3、字面类型的数组类型
4、当该类是class、struct或union时(满足所有)
    4.1 有一个平凡的析构函数(即析构函数为系统默认的析构函数,而非用户实现的)
    4.2 所有构造函数的初始化中的所有非静态数据成员都用常量表达式来初始化
    4.3 是一个聚合类型  或  闭包类型【C++17起】  或  至少有一个constexpr修饰(可以是模板)的复制或移动构造函数
    4.4 所有非静态数据成员和基类都是字面类型【截至C++17】
    4.5 对于非union类型,所有非静态数据成员和基类都不是非volatile的字面类型【C++17起】
    4.6 对于union类型,至少一个非静态数据成员是非volatile的字面类型【C++17起】
5、void类型【C++14起】

6、__is_empty

功能:判断一个类型是否是空类型
条件(同时满足):
1、除了位数为0的位域变量外,没有非静态数据成员
2、不是union类型
3、无虚函数
4、无虚基类
5、无非空类型的基类

7、__is_polymorphic

功能:判断一个类型是否是多态类型
条件(同时满足):
1、不是共用体类型
2、声明或继承了至少一个虚函数

8、__is_constructible

功能:判断一个类型与另外的类型是否可构造。(当另外的类型是多个class类型时,恒为false,暂时不知道为什么)
条件(同时满足):
1、该类存在以另外的类型为参数的构造函数
2、在对应构造函数的参数列表中,参数类型的顺序与提供的“另外的类型”的顺序相同

例子:

#include <iostream>

struct A
{ };
struct B
{
    B(const A &) { }
};
struct C
{
    C(int, double) { }
};
struct D
{
    D(A, B, C)
    { }
};
struct E
{
    E(A &, B &, C &)
    { }
};
struct F
{
    F(const A &, const B &, const C &)
    { }
};
struct G
{
    G(const A&) { }
    G(const B&) { }
    G(const C&) { }
    G(const A&, const B &, const C &) { }
};
int main()
{
    std::cout << std::boolalpha;
    std::cout << "A(B): " << __is_constructible(A, B) << std::endl;
    std::cout << "B(A): " << __is_constructible(B, A) << std::endl;
    std::cout << "B(C): " << __is_constructible(B, C) << std::endl;
    std::cout << "B(C,A): " << __is_constructible(B, C, A) << std::endl;
    std::cout << "D(A,B): " << __is_constructible(D, A, B) << std::endl;
    std::cout << "D(A,B,C): " << __is_constructible(D, A, B, C) << std::endl;
    std::cout << "E(A,B,C): " << __is_constructible(E, A, B, C) << std::endl;
    std::cout << "F(A,B,C): " << __is_constructible(F, A, B, C) << std::endl;
    std::cout << "G(A,B,C): " << __is_constructible(G, A, B, C) << std::endl;
    std::cout << "G(A): " << __is_constructible(G, A) << std::endl;
    std::cout << "C(int,double): " << __is_constructible(C, int, double) << std::endl;
    return 0;
}

运行结果:

9、__is_trivially_constructible

功能:判断一个类型与另外的类型是否可构造,且过程无“非平凡”操作
条件(同时满足):
1、__is_constructible为true
2、该类的“另外的类型”的成员没有任何非平凡的操作

10、__is_assignable

功能:判断一个类型是否存在以另一个类型为参数类型的“拷贝函数”
条件(满足任意):
1、提供的两个类型参数中,左边的类型提供了以右边的类型为参数的赋值运算符重载函数
2、提供的两个类型参数中,左边的类型提供了以右边的类型为参数的构造函数

11、__is_trivially_assignable

功能:判断一个类型是否存在以另一个类型为参数类型的“拷贝函数”,且过程无“非平凡”操作
条件(同时满足):
1、__is_assignable为true
2、过程无“非平凡”操作

12、__has_trivial_destructor

功能:判断一个类型是否存在平凡的析构函数(即系统默认的构造函数)

13、__has_virtual_destructor

功能:判断一个类型是否存在虚析构函数

14、__is_base_of

功能:判断一个类型是否是另一个类型的基类

15、__is_final

功能:判断一个类型是否有final关键字修饰(final作用:不可继承)

16、__is_abstract

功能:判断一个类型是否是抽象类(即存在纯虚函数)

17、__underlying_type

功能:获取一个枚举类型的基本类型(即枚举成员的类型)

例子:

#include <iostream>
#include <typeinfo>

enum A { };
enum B : unsigned { };
enum class C : long long { };

int main()
{
    std::cout << "A type: " << typeid (__underlying_type(A)).name() << std::endl;
    std::cout << "B type: " << typeid (__underlying_type(B)).name() << std::endl;
    std::cout << "C type: " << typeid (__underlying_type(C)).name() << std::endl;
    return 0;
}

运行结果:

类型对照表:

18、__is_aggregate

功能:判断一个类型是否是聚合类型
条件(满足任意):
1、数组类型
2、class、struct、union时(同时满足):
    2.1 没有私有  或  保护【C++17起】的非静态数据成员
    2.2 没有用户声明的构造函数【截至C++11】
    2.3 没有用户提供的构造函数(除非显式声明为default或deleted)【C++11到C++17】
    2.4 没有用户提供的、继承的或声明为explicit的构造函数(除非显式声明为default或deleted)【C++17到C++20】
    2.5 没有用户声明的或继承的构造函数【C++20起】
    2.6 没有虚、私有、保护【C++17起】的基类
    2.7 没有虚成员函数
    2.8 没有默认的成员列表【C++11到C++14】

19、__has_unique_object_representations

功能:判断一个类型是否有独特的对象表示
条件(同时满足):
1、__is_trivially_copyable为true
2、成员的内存排布是紧凑的(空间利用率为100%,没有任何一位是没用的)

 

如果有错误,欢迎指出,谢谢

发布了19 篇原创文章 · 获赞 1 · 访问量 2782

Guess you like

Origin blog.csdn.net/qq811299838/article/details/100626827