Uniform Initialization
Contents
File: ui1.cpp
#include <iostream> #include <map> using namespace std ; class A1 { public: A1( ) { cout << "Default constructor." << endl ; } A1( int i1 ) { } A1( const A1& a1Object ) { cout << "Copy constructor." << endl ; } }; class A2 { int arr[3]; } int main() { int i1 ; //uninitialized variable int i2{} ; //Using Braces int j1(10) ; //initialized variable int j2{ 10 } ; //Using Braces int arr1[] = {1, 2, 3, 4} ; // Aggregate initialization int arr2[]{1, 2, 3, 4} ; //Using Braces A1 a1Object ; //Default Constructor A1 a2Object{} ; // Using Braces A1 b1Object( 3) ; //Parametrized Constructor A1 b1aObject = 3 ; //Parametrized Constructor A1 b2Object{3} ; // Using Braces A1 c1Object = a1Object ; //Copy Constructor A1 c2Object{a1Object} ; // Using Braces // declaring a dynamic array // and initializing using braces int* p1 = new int[5]{ 1, 2, 3, 4, 5 }; return 0 ; }We can also use the braces to initialize an array declared in a class.
File: ui2.cpp
#include <iostream> #include <map> using namespace std ; class A1 { public: int arr1[5] ; A1( ) : arr1{1, 2, 3, 4, 5} { //Pre c++ 11 // for (int i1 = 1; i1 <= 5; ++i1) { // myArray[i1] = i1 ; // Assign values // } cout << "Default constructor." << endl ; for( int x1 : arr1 ) cout << x1 << endl ; } A1( int i1 ) { } A1( const A1& a1Object ) { cout << "Copy constructor." << endl ; } }; int main() { return 0 ; }
std::initializer_list
The "initializer_list" is a new class in C++11. It is a fixed size sequence container. We cannot add or delete elements from it once we have the object. If we have a curly braces with a list then that can be used to construct this class. The STL containers also have an overloaded constructor with this class allowing the containers to be constructed with curly brackets. It can be used in a range based loop and as a parameter to a function. The "initializer_list" does not actually contain the elements but points to the elements that are created. It can be throught of as a view.File: list1.cpp
// C++ program to demonstratethe use of initializer_list as // return type. #include <initializer_list> #include <iostream> #include <vector> using namespace std; void getNumbers( initializer_list<int> myList ) { for( int x1 : myList ) { cout << x1 << " " ; } cout << endl ; } /* list1.cpp:20:21: warning: returning temporary ‘initializer_list’ does not extend the lifetime of the underlying array [-Winit-list-lifetime] 20 | return { 1, 2, 4 } ; initializer_list<int> getNumbers1( ) { // A temporary array is created that will be destroyed once //this function ends. return { 1, 2, 4 } ; } */ int main() { //initializer_list<int> num = getNumbers( { 3, 2, 1} ) ; getNumbers( { 3, 2, 1} ) ; initializer_list<int> i1{-3, -2, -1} ; //Can't access an element in the middle. //cout << i1[2] << endl ; //can iterate through the list. initializer_list<int>::iterator iter1 = i1.begin() ; for( ; iter1 != i1.end() ; iter1++ ) cout << *iter1 << " " ; cout << endl ; //Can be used in a range-based loop for( int x1 : i1 ) cout << x1 << " " ; cout << endl ; vector v1( i1 ) ; return 0; } $ g++ list1.cpp ; ./a.exe 3 2 1 -3 -2 -1 -3 -2 -1
std::array
It is a fixed size container that is more safer than the traditional arrays.It has a function "at()" for bounds checking.at() for bounds-checked element access, throwing an exception on out-of-bounds access. front() and back() to access the first and last elements. size() to retrieve the array's size. fill() to set all elements to a specific value. data() to get a pointer to the underlying C-style array, useful for interoperability with C-style functions. Support for iterators, enabling use with range-based for loops and STL algorithm
File: arr1.cpp
#include <initializer_list> #include <iostream> #include <vector> #include <array> using namespace std; int main() { // Declare and initialize a array of 5 integers array<int, 5> numbers = {1, 2, 3, 4, 5}; // Access elements using the bracket operator cout << "Element at index 2: " << numbers[2] << endl; // Output: 3 // Access elements with bounds checking using at() try { cout << "Element at index 4: " << numbers.at(14) << endl; // Output: 5 // cout << numbers.at(5) << endl; // This would throw an exception } catch (const out_of_range& e1) { cerr << "Error: " << e1.what() << endl; } // Iterate using a range-based for loop cout << "All elements: "; for (int num : numbers) { cout << num << " "; } cout << endl; array<int, 5>::iterator iter1 = numbers.begin() ; for ( ; iter1 != numbers.end() ; iter1++ ) { cout << *iter1 << " "; } cout << endl; // Get the size of the array cout << "Array size: " << numbers.size() << endl; // Output: 5 return 0; } $ g++ arr1.cpp ; ./a.exe Element at index 2: 3 Element at index 4: Error: array::at: __n (which is 14) >= _Nm (which is 5) All elements: 1 2 3 4 5 1 2 3 4 5 Array size: 5
Exercise
1)File: ui_ex1.cpp
#include <initializer_list> #include <iostream> #include <vector> #include <array> using namespace std; int main() { //Define an initializer list of 3 elements 100 200 300 //Try changing the first element using the //iterator notation //Print the list using the range based loop //Define a std::array of 3 elements 100 200 300 //Try changing the first element using the //iterator notation //Print the array using the range based loop return 0; }2)
File: ui_ex2.cpp
#include <initializer_list> #include <iostream> #include <vector> #include <array> #include <set> using namespace std; void method1( vector<int> v1 ) { } void method2( set<int> s1 ) { } int main() { //Define an initializer list of 3 elements 1 2 3 //using just the curly braces. Do not use any variables //Call the method1 and method2 using this approach. return 0; }
1) File: ui_ex1_s.cpp
2) File: ui_ex2_s.cpp