blob: 59b919e890ab1a814ec347f30610244fe3e0bb1e [file] [log] [blame]
Edwin Vanee4e7c242013-03-09 03:33:50 +00001.. index:: Use-Auto Transform
Edwin Vane3b9f08d2013-03-08 23:26:00 +00002
3==================
4Use-Auto Transform
5==================
6
7The Use-Auto Transform is responsible for using the ``auto`` type specifier for
8variable declarations to *improve code readability and maintainability*. The
Eric Christopher6cddedc2013-04-22 14:39:46 +00009transform is enabled with the :option:`-use-auto` option of
Chandler Carruthd9063c42013-09-04 17:35:07 +000010:program:`clang-modernize`. For example:
Edwin Vane3b9f08d2013-03-08 23:26:00 +000011
12.. code-block:: c++
13
14 std::vector<int>::iterator I = my_container.begin();
15
16 // transforms to:
17
18 auto I = my_container.begin();
19
20The ``auto`` type specifier will only be introduced in situations where the
21variable type matches the type of the initializer expression. In other words
22``auto`` should deduce the same type that was originally spelled in the source.
23However, not every situation should be transformed:
24
25.. code-block:: c++
26
27 int val = 42;
28 InfoStruct &I = SomeObject.getInfo();
29
30 // Should not become:
31
32 auto val = 42;
33 auto &I = SomeObject.getInfo();
34
35In this example using ``auto`` for builtins doesn't improve readability. In
36other situations it makes the code less self-documenting impairing readability
37and maintainability. As a result, ``auto`` is used only introduced in specific
38situations described below.
39
40Iterators
41=========
42
43Iterator type specifiers tend to be long and used frequently, especially in
44loop constructs. Since the functions generating iterators have a common format,
45the type specifier can be replaced without obscuring the meaning of code while
46improving readability and maintainability.
47
48.. code-block:: c++
49
50 for (std::vector<int>::iterator I = my_container.begin(),
51 E = my_container.end();
52 I != E; ++I) {
53 }
54
55 // becomes
56
57 for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) {
58 }
59
60The transform will only replace iterator type-specifiers when all of the
61following conditions are satisfied:
62* The iterator is for one of the standard container in ``std`` namespace:
63
64 * ``array``
65
66 * ``deque``
67
68 * ``forward_list``
69
70 * ``list``
71
72 * ``vector``
73
74 * ``map``
75
76 * ``multimap``
77
78 * ``set``
79
80 * ``multiset``
81
82 * ``unordered_map``
83
84 * ``unordered_multimap``
85
86 * ``unordered_set``
87
88 * ``unordered_multiset``
89
90 * ``queue``
91
92 * ``priority_queue``
93
94 * ``stack``
95
96* The iterator is one of the possible iterator types for standard containers:
97
98 * ``iterator``
99
100 * ``reverse_iterator``
101
102 * ``const_iterator``
103
104 * ``const_reverse_iterator``
105
106* In addition to using iterator types directly, typedefs or other ways of
107 referring to those types are also allowed. However, implementation-specific
108 types for which a type like ``std::vector<int>::iterator`` is itself a
109 typedef will not be transformed. Consider the following examples:
110
111.. code-block:: c++
112
113 // The following direct uses of iterator types will be transformed.
114 std::vector<int>::iterator I = MyVec.begin();
115 {
116 using namespace std;
117 list<int>::iterator I = MyList.begin();
118 }
119
120 // The type specifier for J would transform to auto since it's a typedef
121 // to a standard iterator type.
122 typedef std::map<int, std::string>::const_iterator map_iterator;
123 map_iterator J = MyMap.begin();
124
125 // The following implementation-specific iterator type for which
126 // std::vector<int>::iterator could be a typedef would not be transformed.
127 __gnu_cxx::__normal_iterator<int*, std::vector> K = MyVec.begin();
128
129* The initializer for the variable being declared is not a braced initializer
130 list. Otherwise, use of ``auto`` would cause the type of the variable to be
131 deduced as``std::initializer_list``.
132
133Known Limitations
Edwin Vane8d286462013-06-14 15:14:20 +0000134=================
Edwin Vane3b9f08d2013-03-08 23:26:00 +0000135* If the initializer is an explicit conversion constructor, the transform will
136 not replace the type specifier even though it would be safe to do so.
137* User-defined iterators are not handled at this time.