C++11/C++14 Type Inference (auto) and Range-based for loop - 2020
"If you're an experienced C++ programmer and are anything like me, you initially
approached C++11 thinking, "Yes, yes, I get it. It's C++, only more so." But as you
learned more, you were surprised by the scope of the changes. auto declarations,
range-based for loops, lambda expressions, and rvalue references change the face of
C++, to say nothing of the new concurrency features. And then there are the
idiomatic changes. 0 and typedefs are out, nullptr and alias declarations are in.
Enums should now be scoped. Smart pointers are now preferable to built-in ones.
Moving objects is normally better than copying them.
- Effective Modern C++ by Scott Meyers
In C++03, we must specify the type of an object when we declare it. Now, C++11 lets us declare objects without specifying their types.
auto a = 2; // a is an interger auto b = 8.7; // b is a double auto c = a; // c is an integer
Also, the keyword auto is very useful for reducing the verbosity of the code. For instance, instead of writing
for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)we can use the shorter version:
for (auto it = v.begin(); it != v.end(); ++it)
#include <vector> int main() { std::vector<int> a, b; std::vector<int> v{ 1, 2, 3, 4, 5 }; for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) a.push_back(*it); for (auto it = v.begin(); it != v.end(); ++it) b.push_back(*it); }
The keyword decltype can be used to determine the type of an expression at compile-time. For example:
#include <vector> int main() { const std::vector<int> v(1); auto a = v[0]; // a has type int decltype(v[1]) b = 1; // b has type const int&, the return type of // std::vector<int>::operator[](size_type) const auto c = 0; // c has type int auto d = c; // d has type int decltype(c) e; // e has type int, the type of the entity named by c decltype((c)) f = c; // f has type int&, because (c) is an lvalue decltype(0) g; // g has type int, because 0 is an rvalue }
Note that the type denoted by decltype can be different from the type deduced by auto.
C++11 extends the syntax of the for statement to allow for easy iteration over a range of elements.
This form of for will iterate over each element in the list. It will work for C-style arrays, initializer lists, and any type that has begin() and end() functions defined for it that return iterators.
All of the standard library containers that have begin/end pairs will work with the range-based for statement.
#include <iostream> #include <vector> int main() { std::vector<int> a, b; std::vector<int> v{ 1, 2, 3, 4, 5 }; // C++03 for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) a.push_back(*it); // C++11 for (auto it = v.begin(); it != v.end(); ++it) b.push_back(*it); for (int item : a) std::cout << item << " "; // read only access std::cout << std::endl; for (auto &item; : b) { item *= 10; std::cout << item << " "; // read only access } }
Output:
1 2 3 4 5 10 20 30 40 50
C++11/C++14 New Features
initializer_list
Uniform initialization
Type Inference (auto) and Range-based for loop
The nullptr and strongly typed enumerations
Static assertions and Constructor delegation
override and final
default and delete specifier
constexpr and string literals
Lambda functions and expressions
std::array container
Rvalue and Lvalue (from C++11 Thread tutorial)
Move semantics and Rvalue Reference (from C++11 Thread tutorial)
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization