Initializer

(), {} and std::initializer_list

1. Commons and distinctions between () and {}

() {}
Commons Direct initialization

    int x(3);
    int x{3};
    std::string name("Some Name");
    std::string name{"Some Name"};
    int* y = new int(1);
    int* y = new int{1};
    

Call constructors

    MyClass mc(1);
    MyClass mc{1}; // If no initializer list constructor exists.
    
Distincetions Narrowing Conversions
int pi(3.14);  // OK -- pi == 3.
int pi{3.14};  // Compile error: narrowing conversion.
Uniform Initialization
std::vector v(100, 1);  // A vector containing 100 items: All 1s.
std::vector v{100, 1};  // A vector containing 2 items: 100 and 1.

2. std:: initializer_list

Using std::initializer_list allows a class to be constructed with a list of values, providing flexibility and ease of initialization.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template<typename T>
struct S {
S(std::initializer_list<T> data) : _data(data) {
std::cout << "initializer_list contructor called\n";
}
S(T a, T b, T c) {
std::cout << "3 params contructor called\n";
}
private:
std::initializer_list<T> _data;
};

int main() {
S<int> s1{1, 2, 3}; // Ok, initializer_list contructor called.
S<int> s2(1, 2, 3); // Ok, 3 params contructor called.
S<int> s3{1.1, 2.2, 3.3}; // Error, narrowing conversion.
return 0;
}

{} provides a more safer way(prevent type conversion) for initialization. In situations where {} and () are equivalent, we should choose {} over ();

References

Author

Joe Chu

Posted on

2024-05-27

Updated on

2024-05-27

Licensed under

Comments