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