Инициализация вектора‹строка› двойными фигурными скобками

Может ли кто-нибудь объяснить разницу в поведении между инициализацией с помощью двойных и одинарных фигурных скобок в приведенном ниже примере?

Код 1:

vector<string> v = {"a", "b"};
string c(v[0] + v[1]);
cout << "c = " << c;
cout << "c.c_str() = " << c.c_str();

Вывод №1:

c = ab
c.c_str() = ab

Код 2:

vector<string> v = {{"a", "b"}};
string c(v[0] + v[1]);
cout << "c = " << c;
cout << "c.c_str() = " << c.c_str();

Вывод №2:

c = a\acke�Z\ 
c.c_str() = a

person Shir    schedule 10.10.2017    source источник
comment
Я тестирую код № 2 и выбрасываю исключение в строке: vector<string> v = {{"a", "b"}};   -  person Farhad    schedule 10.10.2017


Ответы (1)


Централизованное неявное преобразование. Вот что происходит.

  1. vector<string> v = {"a", "b"}; Вы инициализируете вектор, предоставляя список инициализаторов с двумя элементами. Два std::string инициализируются из строковых литералов, а затем копируются в вектор.

  2. vector<string> v = {{"a", "b"}}; Вы инициализируете вектор, предоставляя инициализатор с одним элементом. И этот единственный std::string инициализируется из инициализатора, который имеет два элемента. Доступ ко второму элементу вектора имеет неопределенное поведение.

А теперь самое интересное. Ваш второй фрагмент имеет неопределенное поведение даже до того, как вы получите доступ к v[1]. Разрешение перегрузки (для создания одного std::string) выбирает конструктор. Лучший жизнеспособный, это:

template< class InputIt >
basic_string( InputIt first, InputIt last, 
              const Allocator& alloc = Allocator() );

При этом InputIt выводится как char const [2] (и настройка параметра функции, превращая его в char const*). Поскольку на самом деле это не итераторы, весь ад вырывается на свободу.

person StoryTeller - Unslander Monica    schedule 10.10.2017
comment
см. stackoverflow.com/questions/46665914/ Может быть, вы могли бы объяснить разницу - person bolov; 10.10.2017
comment
Разве пример № 2 не должен даже компилироваться? Зачем компилятору смотреть на {a, b} и говорить: Да, это строка...?? - person PeterT; 01.05.2019
comment
@PeterT - Это не говорит об этом. Там написано, могу ли я сделать из него нить. И, к сожалению, может. - person StoryTeller - Unslander Monica; 01.05.2019