In this article we will about study C-style array vs std::array. A std::array should have same run-time performance as a c-style array. In STL there are two type of arrays, first is fixed length array means std::array and other type is dynamic array means std::vector.
Introduced in C++11, std::array has a unique characteristic among all sequential containers of the STL, you can not adjust it size during run-time.
Initialization of std::array
std::array initialized by following ways:
// Required header file #include <array> // Declare an integer array with length 4 std::array<int, 4> myArray;
// Initialization list std::array<int, 5> myArray = { 9, 8, 5, 3, 1 };
// Uniform initialization std::array<int, 5> myArray { 9, 8, 5, 3, 1 };
// The 10 elements are not initialized. std::array<int,10> myArray ;
The 10 elements are value-initialized to zero. std::array<int,10> myArray {};
// Legal, elements 3 and 4 are set to zero! std::array<int> myArray = { 9, 7, 5};
// Illegal, array length must be provided std::array<int, > myArray = { 9, 8, 5, 3, 1 };
// Illegal, too many elements in initializer list! std::array<int, > myArray = { 0, 1, 2, 3, 4, 5 };
Index access
std::array supports the index access in 3 ways :
- myArray[n-1]: Access to the nth element without a check of the array boundaries.
- myArray.at(n-1): Access to the nth element with a check of the array boundaries. Eventually, a std::range_error exception is thrown.
- std::get
(myArray): Access to the nth element with a check of the array boundaries at compile time. The syntax is according to std::tuple. std::get (myArray) shows the relationship of std::array with std::tuple. std::array is a homogeneous container of fixed size while std::tuple is a heterogeneous container of fixed size.
Example: C-Style array Vs std::array
#include <iostream> #include <array> #include <vector> int main() { // c-style array int array1[3] = {1, 2, 3}; array1[1] = 15; std::cout << "size: " << (sizeof(array1) / sizeof(*array1)) << std::endl; for (auto element : array1) { std::cout << element << std::endl; } // std-style array std::array<int,3> array2 = { 4, 5, 6 }; array2[1] = 25; std::cout << "size: " <<array2.size() << std::endl; for (auto element : array2) { std::cout << element << std::endl; } }Here, array2.size() will return array size, no need of calculation like - (sizeof(array1) / sizeof(*array1)).
Array as method parameter:
Using below way you can pass std::array as string parameter :
#include <iostream> #include <vector> #include <array> void PrintArray(int* values, int size) { std::cout << "size: " << size << std::endl; for (int i = 0; i < size; ++i) { std::cout << values[i] << std::endl; } } void PrintArray(const std::array<int,3> &values) { std::cout << "size: " << values.size() << std::endl; for (auto& value : values) { std::cout << value << std::endl; } } int main() { int array1[3] = { 1, 2, 3 }; PrintArray(array1, 3); std::array<int,3> array2 = { 4, 5, 6 }; PrintArray(array2); }
Array as return value
#include <iostream> #include <vector> #include <array> int* CreateArray() { int* array = new int[3] { 1, 2, 3 }; return array; } std::array<int,3> CreateStdArray() { std::array<int,3> array = { 4, 5, 6 }; return array; } int main() { // c-style array int* array1 = CreateArray(); int size = 3; // you have to know the size of the array for (int i = 0; i < size; ++i) { std::cout << array1[i] << std::endl; } delete[] array1; // you have to delete the array // std-style array std::array<int,3> array2 = CreateStdArray(); for (auto element : array2) { std::cout << element << std::endl; } }In this case called method should know data type and size of array before calling function, for variable length of array std::array is not useful.
Sort std::array
Using std::sort algorithm we can sort std::array elements. If any error occurred during execution will throw an out of range exception..
#include <iostream> #include <vector> #include <array> #include <algorithm> int main() { // c-style array int array1[3] = {7, 5, 3}; std::sort(std::begin(array1), std::end(array1)); for (auto element : array1) { std::cout << element << std::endl; } // std-style array std::array<int,3> array2 = { 7, 5, 3 }; std::sort(array2.begin(), array2.end()); for (auto element : array2) { std::cout << element << std::endl; } }
Multi-dimensional arrays
The std::array as well as the c-style array support multidimensions. These multidimensions are designed as arrays of nested arrays.
#include <iostream> #include <array> int main() { // c-style array int array1[2][3] = { { 1, 2, 3 }, { 4, 5, 6} }; array1[0][1] = 10; for (auto &row : array1) { for (auto &element : row) { std::cout << element << std::endl; } } // std-style array std::array<std::array<int,3>, 2> array2{ { { 7, 8, 9 }, { 10, 11, 12 } } }; array2[0][1] = 20; for (auto &row : array2) { for (auto &element : row) { std::cout << element << std::endl; } } }
Summary
The std::array is designed as zero-overhead wrapper for c-style arrays. Therefore, it comes with all the advantages of a c-style array and ads the additional advantages of C++ containers. I would recommend to use std::arrays except you have a rare special use case which comes with good reasons to use a c-style array.
Advantages of std::array
- Perfectly matches with the strict type system concept of c++
- Copy semantic / no pointer decay / the array doesn’t convert to a pointer unless you explicitly ask it to
- It knows its size
- Range check in debug builds
- No memory overhead beyond what it needs to hold its elements
- Same performance as a c-style array
- Direct support of use in STL algorithms
Disadvantages of std::array
- Slightly more awkward syntax for declaration of the array, especially when creating multi-dimensional arrays
No comments:
Post a Comment