Brace Initialization: Introduction

Motivation: Inconsistent Initialization Styles

Initialization was always inconsistent ⟶ Extremely confusing, especially for newbies!

  • Integral types

  • Aggregates (struct, array)

  • Class objects

  • Container (e.g. std::vector) initialization with contained values ⟶ push_back() orgies

Motivation: Integral Types Initialization

Integral Types

  • Two different kinds of initialization

  • A matter of history

  • Initialization and assignment are different

  • Constructor style necessary in templates ⟶ integers have to behave as if they were objects

Integer Initialization

int x = 7; // assignment style
int y(42); // ctor style

Motivation: Aggregate Initialization

Aggregates

  • Initialization goes like it used to go in good old C

  • No constructor style

Aggregate Initialization

int arr[] = {1, 2, 3};

struct s { int i,j; }
s s1 = {1, 2};
s s2 = {1}; // s2.j==0

Motivation: Object Initialization/Constructor

Objects

  • Constructor: looks like function call

  • Copy initialization

Object Initialization

class C {
public:
  C(int i, int j);
};

C c1(1,2);
C c2 = c1;

Motivation: Container Initialization (Missing Pre C++11)

Containers

  • Filling containers is extremely cumbersome ⟶ .push_back()

  • Initialization requires an existing container ⟶ very very loud

Container Initialization

int arr[] = {1,2,3};
vector<int> v1(arr, arr+3);
vector<int> v2(v1.cbegin(), v1.cend());

set<int> s;
s.insert(1);
s.insert(2);
vector<int> v(s.cbegin(), s.cend());

Motivation: Member Array Initialization

Member Arrays

  • Cannot be initialized

  • Must be filled in constructor body

  • ⟶ inconsistent

  • ⟶ loud

  • ⟶ workarounds

Member Array Initialization

class C {
public:
  C() : data_(/*dammit!*/) {}
private:
  const int data_[3];
};

Motivation: Heap Array Initialization

Arrays on the Heap

  • Cannot be initialized

  • ⟶ inconsistent

  • ⟶ loud

  • ⟶ workarounds

Heap Array Initialization

const int *arr = new int[42];
// and now?

Solution: Brace Initialization In C++11

Solution: brace initialization everywhere ⟶ the language becomes …

  • Clear

  • Readable

  • Memorizable (less exceptions)

  • Attractive?

Good: Refuses To Narrow Built-In Types

int i = 1.5;       // <--- silently narrowing to 1
int j{1.5};        // <--- error: narrowing conversion of ‘1.2e+0’ from ‘double’ to ‘int’

Examples

  • Integer initialization

    int i{42};
    int j{};  // initialized with 0
    
  • Array initialization

    int arr[]{1,2,3};
    
  • Struct initialization

    struct s { int i,j; }
    s s1{1,2};
    
  • Container Initialization

    std::vector<int> v{1,2,3};
    std::map<int, std::string{ {1, "one"}, {2, "two"}, };
    
  • Member array initialization

    class C {
    public:
      C() : data_{1,2,3} {}
    private:
      const int data_[3];
    };
    
  • Heap array initialization

    const int *arr = new const int[3]{1,2,3};