Ответ 1
Поведение initializer_list ошибочно. В своем деструкторе он вызывает векторное удаление (a delete []) всего диапазона, а затем снова удаляет первую запись в массиве. Это поведение не является частью класса initializer_list и выглядит как ошибка компилятора. initializer_list не имеет деструктора и не выделяет массив, используемый для списка. Он просто выглядит как оболочка для массива C.
Что касается использования дополнительной копии, которую вы видите, это вызвано изменением размера вектора во время его инициализации. Вот ваш поток:
Init 00B7FAE8 // construct "foo"
Init 00B7FBE8 // construct "bar"
Copy 00E108A0 // copy "foo" to vector (capacity=1)
Copy 00E10AE8 (?????) // copy the above object to the resized vector (capacity = 2)
Deleting b 00E108A0 // delete the smaller vector buffer
Copy 00E10BE8 // copy "bar" from initialization_list to vector
Deleting b 00B7FBE8 // delete initialization_list in reverse order. this is "bar"
Deleting b 00B7FAE8 // last to delete. this is "foo"
Deleting b 00B7FAE8 (bug)
// later C::bs is destroyed
Что вы видите здесь, это инициализация вектора через push_back довольно медленно из-за копирования. Это произойдет, даже если вы использовали более элегантный способ:
C(initializer_list<B> bb) : bs(bb) {}
Более быстрый (без дополнительных копий) метод:
C(initializer_list<B> bb) {
bs.reserve(bb.size());
bs.insert(bs.end(), bb.begin(), bb.end());
}