Почему список инициализаторов имеет другой результат по сравнению с списком выражений - PullRequest
0 голосов
/ 08 июня 2018

Я чувствую себя странно, когда пишу код ниже.Я с нетерпением жду того же результата, но это оказывается неправильно.Почему 2 оператора имеют разный вывод, и в чем разница между (expression-list) и {initializer-list}?

cout << string(4, 'c') << endl;  
cout << string{ 4, 'c' } << endl; 

вывод:

cccc  
c   //a square '' before 'c'

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

С cppreference.com :

В противном случае конструкторы T рассматриваются в два этапа:

  • Все конструкторы, которые принимают std::initializer_list в качестве единственного аргумента или в качестве первого аргумента, если оставшиеся аргументы имеют значения по умолчанию, проверяются и сопоставляются по разрешению перегрузки с одним аргументом типа std::initializer_list

  • Если предыдущий этап не дает совпадения, все конструкторы T участвуют в разрешении перегрузки для набора аргументов, который состоит из элементов braced-init-list , сограничение, что разрешены только не сужающие преобразования.Если на этом этапе создается явный конструктор как наилучшее совпадение для copy-list-initialization , компиляция завершается неудачно (обратите внимание, что в простом copy-initialization явные конструкторы вообще не рассматриваются).

В вашем случае

string(4, 'c')

использует следующий конструктор.

std::string(size_type count, 
            char ch, 
            const Allocator& alloc = Allocator() );

С другой стороны,

string{ 4, 'c' }

использует следующий конструктор.

std::string(std::initializer_list<char> ilist, 
            const Allocator& alloc = Allocator() );

Если бы второй конструктор не был определен в std::string, обаиз них были бы произведены идентичные объекты.

0 голосов
/ 08 июня 2018

Оба являются вызовами конструктора , но они вызывают два разных конструктора.Первый вызов («2» в ссылке) создает число символов, поэтому в вашем случае вы получаете 4 символа «c».

Второй конструктор (в ссылке «9») занимает std::initializer_list,Когда вы создаете использование скобок вместо паренов, , если , у класса есть конструктор, принимающий initializer_list, он всегда будет иметь приоритет.

Если это утешит, это поведение поставит в тупик лот программистов за эти годы ...

...