---
# System prepended metadata

title: 波括弧初期化
tags: [elkurin-daily-note, C++-General]

---

# 波括弧初期化

C++で波括弧を使う初期化をしばしば見かける。
```cpp=
base::WeakPtrFactory<ClassName> weak_factory_{this};
```

## 一様初期化
一様初期化 / uniform initialization というらしい。  
初期化が書きやすくて助かる。  
使用例：
```cpp=
void GetVec(std::vector<int> vec);

// 空を渡したい時、こう書きがち
GetVec(std::vector<int>());

// 波括弧だとかんたんになる
GetVec({});


// 配列のoptionalのときとか使いたくなる
optional_vector.value_or({});
```

型推論をある程度してくれるので、型を長々書かなくて良い。  
autoで受け取る初期化リストは[std::initialilzer_list](https://cpprefjp.github.io/reference/initializer_list/initializer_list.html)として推論される。この型は初期化リストによる初期化を助ける。
```cpp=
template <class T>
class Hoge {
  Hoge(std::initializer_list<T> init_list)
    : data_(init.begin(), init.end()) {}
}
```

型の推論は限界がある。  
テンプレートに対して渡して推論させることはできない。
```cpp=
template <class T>
void f(T t) {}

// 型がわからない
f({1});
```

## int配列とuniform initialization
実際に誤読したのが以下の例。
```cpp=
// 1と2の2つの要素からなるvector。初期化リストに1, 2が入る。
std::vector<int> a{1, 2};

// ひとつの2からなるvector。vectorのctorにある、同じ値でn個初期化する構文。
std::vector<int> b(1, 2);
```
{}と()で意味が違う。  
特に、こういったコンストラクタは初期化リストとconflictしてしまい、波括弧で呼び出すことはできなさそう。  
初期化用の構文で一部の初期化ができないのはちょっとキモい。

## 初期化順
波括弧では初期化順が前から順に保証されるが、普通の括弧では順不同。

確かめてみた。
```cpp=
char x() {
  std::cout << "x" << std::endl;
  return 'x';
}

char y() {
  std::cout << "y" << std::endl;
  return 'y';
}

char z() {
  std::cout << "z" << std::endl;
  return 'z';
}

struct hoge {
  hoge(int, int, int) {}
};

int main(void) {
  hoge nami{x(), y(), z()};
  std::cout << std::endl;
  hoge kakko(x(), y(), z());
  return 0;
}
```
このとき`nami`の方はx->y->zだったが`kakko`のほうはz->y->xだった。  
何度か走らせたが決定的っぽい。  
コンパイラ次第かな？