C++11 trivial, standard_layout, POD的好处和STL类型属于哪种?

  C++11引进了更加完善的类型系统。包括将原本的POD类型细分为: trivial和standard_layout类型,同时具有这两个的就是POD。

 

  trivial好处

        支持静态初始化,就是C-style array, struct和array<int>使用{}的初始化方式。注:vector等的初始化列表不属于静态初始化。

        是拷贝不变的(trivially copyable)的class,可以使用memcpy, memmove不改变它的语义。

  standard_layout好处:

        它对语言间交互很有用,这是因为C++ standard-layout类型和C中struct或union类型有相同的内存布局。

        但是,它不满足trival的两个好处。

 

  

  检测:标准模板块(STL)在头文件<type_traits>中定义了对这些类型的检测

    #include <type_traits>

    template <typename T>
    struct std::is_pod;


    template <typename T>
    struct std::is_trivial;


    template <typename T>
    struct std::is_trivially_copyable;


      template <typename T>
    struct std::is_standard_layout;

 

  

  对C++11中一些类型的测试:windows 7 + Cygwin + gcc version 4.8.2 (GCC)

  1 #include <iostream>
  2 #include <list>
  3 #include <deque>
  4 #include <vector>
  5 #include <array>
  6 #include <map>
  7 #include <set>
  8 #include <type_traits>
  9 #include <string>
 10 #include <memory>
 11 #include <unordered_set>
 12 #include <unordered_map>
 13 #include <utility>            //for pair
 14 
 15 using std::shared_ptr;
 16 using std::unique_ptr;
 17 using std::unordered_set;
 18 using std::unordered_map;
 19 using std::list;
 20 //using std::is_trivially_copyable;
 21 using std::deque;
 22 using std::vector;
 23 using std::array;
 24 using std::cout;
 25 using std::map;
 26 using std::set;
 27 using std::pair;
 28 using std::endl;
 29 using std::is_pod;
 30 using std::is_trivial;
 31 using std::is_standard_layout;
 32 using std::string;
 33 
 34 int main(void)
 35 {
 36     cout << "int:" << endl;
 37     cout << "is_trivial: " << is_trivial<int>::value << endl;
 38     cout << "is_standard_layout: " << is_standard_layout<int>::value << endl;
 39     cout << "is_pod: " << is_pod<int>::value << endl << endl;
 40     
 41     cout << "string:" << endl;
 42     cout << "is_trivial: " << is_trivial<string>::value << endl;
 43     cout << "is_standard_layout: " << is_standard_layout<string>::value << endl;
 44     cout << "is_pod: " << is_pod<string>::value << endl;
 45     cout << "sizeof(string): " << sizeof(string) << endl << endl;
 46     
 47     cout << "array<int>:" << endl;
 48     cout << "is_trivial: " << is_trivial<array<int, 5>>::value << endl;
 49     cout << "is_standard_layout: " << is_standard_layout<array<int, 5>>::value << endl;
 50     cout << "is_pod: " << is_pod<array<int, 5>>::value << endl << endl;;
 51 
 52     cout << "array<string>:" << endl;
 53     cout << "is_trivial: " << is_trivial<array<string, 5>>::value << endl;
 54     cout << "is_standard_layout: " << is_standard_layout<array<string, 5>>::value << endl;
 55     cout << "is_pod: " << is_pod<array<string, 5>>::value << endl << endl;
 56 
 57     cout << "pair<int, int>:" << endl;
 58     cout << "is_trivial: " << is_trivial<pair<int, int>>::value << endl;
 59     cout << "is_standard_layout: " << is_standard_layout<pair<int, int>>::value << endl;
 60     cout << "is_pod: " << is_pod<pair<int, int>>::value << endl;;
 61     cout << "sizeof(pair<int, int>): " << sizeof(pair<int,int>) << endl << endl;
 62 
 63     cout << "pair<string, string>:" << endl;
 64     cout << "is_trivial: " << is_trivial<pair<string, string>>::value << endl;
 65     cout << "is_standard_layout: " << is_standard_layout<pair<string, string>>::value << endl;
 66     cout << "is_pod: " << is_pod<pair<string, string>>::value << endl;
 67     cout << "sizeof(pair<string, string>): " << sizeof(pair<string, string>) << endl << endl;
 68 
 69     cout << "vector<int>:" << endl;
 70     cout << "is_trivial: " << is_trivial<vector<int>>::value << endl;
 71     cout << "is_standard_layout: " << is_standard_layout<vector<int>>::value << endl;
 72     cout << "is_pod: " << is_pod<vector<int>>::value << endl;;
 73     cout << "sizeof(vector<int>): " << sizeof(vector<int>) << endl << endl;
 74 
 75     cout << "vector<string>:" << endl;
 76     cout << "is_trivial: " << is_trivial<vector<string>>::value << endl;
 77     cout << "is_standard_layout: " << is_standard_layout<vector<string>>::value << endl;
 78     cout << "is_pod: " << is_pod<vector<string>>::value << endl;
 79     cout << "sizeof(vector<string>): " << sizeof(vector<string>) << endl << endl;
 80 
 81     cout << "deque<int>:" << endl;
 82     cout << "is_trivial: " << is_trivial<deque<int>>::value << endl;
 83     cout << "is_standard_layout: " << is_standard_layout<deque<int>>::value << endl;
 84     cout << "is_pod: " << is_pod<deque<int>>::value << endl;;
 85     cout << "sizeof(deque<int>): " << sizeof(deque<int>) << endl << endl;
 86 
 87     cout << "deque<string>:" << endl;
 88     cout << "is_trivial: " << is_trivial<deque<string>>::value << endl;
 89     cout << "is_standard_layout: " << is_standard_layout<deque<string>>::value << endl;
 90     cout << "is_pod: " << is_pod<deque<string>>::value << endl;
 91     cout << "sizeof(deque<string>): " << sizeof(deque<string>) << endl << endl;
 92 
 93     cout << "list<int>:" << endl;
 94     cout << "is_trivial: " << is_trivial<list<int>>::value << endl;
 95     cout << "is_standard_layout: " << is_standard_layout<list<int>>::value << endl;
 96     cout << "is_pod: " << is_pod<list<int>>::value << endl;
 97     cout << "sizeof(list<int>): " << sizeof(list<int>) << endl << endl;
 98 
 99     cout << "list<string>:" << endl;
100     cout << "is_trivial: " << is_trivial<list<string>>::value << endl;
101     cout << "is_standard_layout: " << is_standard_layout<list<string>>::value << endl;
102     cout << "is_pod: " << is_pod<list<string>>::value << endl;
103     cout << "sizeof(list<string>): " << sizeof(list<string>) << endl << endl;
104 
105     cout << "vector<list<int>>:" << endl;
106     cout << "is_trivial: " << is_trivial<vector<list<int>>>::value << endl;
107     cout << "is_standard_layout: " << is_standard_layout<vector<list<int>>>::value << endl;
108     cout << "is_pod: " << is_pod<vector<list<int>>>::value << endl;
109     cout << "sizeof(vector<list<int>>): " << sizeof(vector<list<int>>) << endl << endl;
110 
111     cout << "vector<list<string>>:" << endl;
112     cout << "is_trivial: " << is_trivial<vector<list<string>>>::value << endl;
113     cout << "is_standard_layout: " << is_standard_layout<vector<list<string>>>::value << endl;
114     cout << "is_pod: " << is_pod<vector<list<string>>>::value << endl;
115     cout << "sizeof(vector<list<string>>): " << sizeof(vector<list<string>>) << endl << endl;
116 
117     cout << "set<int>:" << endl;
118     cout << "is_trivial: " << is_trivial<set<int>>::value << endl;
119     cout << "is_standard_layout: " << is_standard_layout<set<int>>::value << endl;
120     cout << "is_pod: " << is_pod<set<int>>::value << endl;
121     cout << "sizeof(set<int>): " << sizeof(set<int>) << endl << endl;
122 
123     cout << "set<string>:" << endl;
124     cout << "is_trivial: " << is_trivial<set<string>>::value << endl;
125     cout << "is_standard_layout: " << is_standard_layout<set<string>>::value << endl;
126     cout << "is_pod: " << is_pod<set<string>>::value << endl;
127     cout << "sizeof(set<string>): " << sizeof(set<string>) << endl << endl;
128 
129     cout << "map<int, int>:" << endl;
130     cout << "is_trivial: " << is_trivial<map<int, int>>::value << endl;
131     cout << "is_standard_layout: " << is_standard_layout<map<int, int>>::value << endl;
132     cout << "is_pod: " << is_pod<map<int, int>>::value << endl;
133     cout << "sizeof(map<int, int>): " << sizeof(map<int, int>) << endl << endl;
134 
135     cout << "map<string, string>:" << endl;
136     cout << "is_trivial: " << is_trivial<map<string, string>>::value << endl;
137     cout << "is_standard_layout: " << is_standard_layout<map<string, string>>::value << endl;
138     cout << "is_pod: " << is_pod<map<string, string>>::value << endl;
139     cout << "sizeof(map<string, string>): " << sizeof(map<string, string>) << endl << endl;
140 
141     cout << "unordered_set<int>:" << endl;
142     cout << "is_trivial: " << is_trivial<unordered_set<int>>::value << endl;
143     cout << "is_standard_layout: " << is_standard_layout<unordered_set<int>>::value << endl;
144     cout << "is_pod: " << is_pod<unordered_set<int>>::value << endl;
145     cout << "sizeof(unorder_set<int>): " << sizeof(unordered_set<int>) << endl << endl;
146 
147     cout << "unordered_set<string>:" << endl;
148     cout << "is_trivial: " << is_trivial<unordered_set<string>>::value << endl;
149     cout << "is_standard_layout: " << is_standard_layout<unordered_set<string>>::value << endl;
150     cout << "is_pod: " << is_pod<unordered_set<string>>::value << endl;
151     cout << "sizeof(unorder_set<string>): " << sizeof(unordered_set<string>) << endl << endl;
152 
153 
154     cout << "unordered_map<int, int>:" << endl;
155     cout << "is_trivial: " << is_trivial<unordered_map<int, int>>::value << endl;
156     cout << "is_standard_layout: " << is_standard_layout<unordered_map<int, int>>::value << endl;
157     cout << "is_pod: " << is_pod<unordered_map<int, int>>::value << endl;
158     cout << "sizeof(unorder_map<int, int>): " << sizeof(unordered_map<int, int>) << endl << endl;
159 
160     cout << "unordered_map<string, string>:" << endl;
161     cout << "is_trivial: " << is_trivial<unordered_map<string, string>>::value << endl;
162     cout << "is_standard_layout: " << is_standard_layout<unordered_map<string, string>>::value << endl;
163     cout << "is_pod: " << is_pod<unordered_map<string, string>>::value << endl;
164     cout << "sizeof(unorder_map<string, string>): " << sizeof(unordered_map<string, string>) << endl << endl;
165 
166     cout << "shared_ptr<int>:" << endl;
167     cout << "is_trivial: " << is_trivial<shared_ptr<int>>::value << endl;
168     cout << "is_standard_layout: " << is_standard_layout<shared_ptr<int>>::value << endl;
169     cout << "is_pod: " << is_pod<shared_ptr<int>>::value << endl;
170     cout << "sizeof(shared_ptr<int>): " << sizeof(shared_ptr<int>) << endl << endl;
171 
172     cout << "unique_ptr<int>:" << endl;
173     cout << "is_trivial: " << is_trivial<unique_ptr<int>>::value << endl;
174     cout << "is_standard_layout: " << is_standard_layout<unique_ptr<int>>::value << endl;
175     cout << "is_pod: " << is_pod<unique_ptr<int>>::value << endl;
176     cout << "sizeof(unique_ptr<int>): " << sizeof(unique_ptr<int>) << endl << endl;
177 
178     return 0;
179 }

  

  程序输出:

  

int: is_trivial: 1 is_standard_layout: 1 is_pod: 1

string: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(string): 4

array<int>: is_trivial: 1 is_standard_layout: 1 is_pod: 1

array<string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0

pair<int, int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(pair<int, int>): 8

pair<string, string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(pair<string, string>): 8

vector<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(vector<int>): 12

vector<string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(vector<string>): 12

deque<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(deque<int>): 40

deque<string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(deque<string>): 40

list<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(list<int>): 8

list<string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(list<string>): 8

vector<list<int>>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(vector<list<int>>): 12

vector<list<string>>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(vector<list<string>>): 12

set<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(set<int>): 24

set<string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(set<string>): 24

map<int, int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(map<int, int>): 24

map<string, string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(map<string, string>): 24

unordered_set<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(unorder_set<int>): 24

unordered_set<string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(unorder_set<string>): 24

unordered_map<int, int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(unorder_map<int, int>): 24

unordered_map<string, string>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(unorder_map<string, string>): 24

shared_ptr<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(shared_ptr<int>): 8

unique_ptr<int>: is_trivial: 0 is_standard_layout: 1 is_pod: 0 sizeof(unique_ptr<int>): 4

 

  结论:内置类型(如: int, float),array<int>是POD类型

       POD类型是递归的,array<string>就不是POD类型,因为string不是

     所有测试类型包括:pair(tuple), vector, list, deque, set, map, unordered_set, unordered_map, shared_ptr, unique_ptr

              都满足 is_standard_layout但是不满足is_trivial,因此也不满足is_pod类型。

     unique_ptr具有和普通指针一样大小,大多数时候应该使用它(当然还有其它原因: 如unique性能更好等等),而不是shared_ptr。

 

 

posted on 2014-04-15 13:29  hancmhi  阅读(2913)  评论(0编辑  收藏  举报