C++11/C++14 std::array container - 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
The new std::array is a container for constant size arrays. It's a sequential container class defined in <array> that specifies a fixed length array at compile time.
It can be initialized with aggregate-initialization, given at most n initializers that are convertible to
T: std::array<int, 5> a = {1, 2, 3, 4, 5};
It combines the performance and accessibility of a C-style array with the benefits of a standard container, such as knowing its own size, supporting assignment, random access iterators, etc.
The following code shows how we handle the std::array container:
/* arr1.cpp */ #include <string> #include <iterator> #include <iostream> #include <algorithm> #include <array> int main() { // construction uses aggregate initialization std::array<int, 5> i_array1{ {3, 4, 5, 1, 2} }; // double-braces required std::array<int, 5> i_array2 = {1, 2, 3, 4, 5}; // except after = std::array<std::string, 2> string_array = { {std::string("a"), "b"} }; std::cout << "Initial i_array1 : "; for(auto i: i_array1) std::cout << i << ' '; // container operations are supported std::sort(i_array1.begin(), i_array1.end()); std::cout << "\nsored i_array1 : "; for(auto i: i_array1) std::cout << i << ' '; std::cout << "\nInitial i_array2 : "; for(auto i: i_array2) std::cout << i << ' '; std::cout << "\nreversed i_array2 : "; std::reverse_copy(i_array2.begin(), i_array2.end(), std::ostream_iterator<int>(std::cout, " ")); // ranged for loop is supported std::cout << "\nstring_array : "; for(auto& s: string_array) std::cout << s << ' '; return 0; }
Output:
$ g++ -std=c++11 -o arr1 arr1.cpp $ ./arr1 Initial i_array1 : 3 4 5 1 2 sored i_array1 : 1 2 3 4 5 Initial i_array2 : 1 2 3 4 5 reversed i_array2 : 5 4 3 2 1
Here is an example of using a simplified version of the std::array class:
/* arr2.cpp */ #include <iostream> using namespace std; template <typename T, int n> class myArray { public: myArray() {a = new T[n];} ~myArray() {delete[] a;} T& operator[](int i) {return *(a+i);} private: T* a; }; int main() { myArray<int, 5> arr; for(int i = 0; i < 5 ; i++) cout << arr[i] << ' '; return 0; }
Output:
$ g++ -std=c++11 -o arr2 arr2.cpp $ ./arr2 0 0 0 0 0
Note that the example is just a demonstration of the way how the implementation for std::array looks like. So, it's very primitive and even we had to override [] operator.
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