C++: особенности рассмотрения, но не вызова конструкторов

На cppreference об инициализации списка во втором намерении (для копирования-списка- инициализация) он говорит:

copy-list-initialization (рассматриваются как явные, так и неявные конструкторы, но могут вызываться только неявные конструкторы)

В чем именно разница между конструкторами, которые «рассматриваются» и фактически «вызываются». Зачем рассматривать конструкторы, которые все равно нельзя вызывать?


person Reizo    schedule 30.10.2018    source источник
comment
Я предполагаю, что это означает, что явные конструкторы также участвуют в разрешении перегрузки, но если такой конструктор оказывается наиболее подходящим, программа плохо сформирована.   -  person HolyBlackCat    schedule 30.10.2018
comment
Я предполагаю, что это означает, что разрешение перегрузки не заботится о том, является ли оно явным, пока не будет выбрана перегрузка.   -  person One Man Monkey Squad    schedule 30.10.2018
comment
почему вообще существуют разные формы инициализации списка? - на самом деле это хороший вопрос (хотя он, вероятно, не вписывается в формат SO). C++ уже имеет 11 (?) форм инициализации без особой причины (и, вероятно, в новых стандартах появится больше). кому-то нужно обуздать стандартный комитет.   -  person user7860670    schedule 30.10.2018
comment
Этот вопрос частично дублируется здесь, вы можете найти полезную информацию, по крайней мере, связанную с вашим последним вопросом. Пожалуйста, прочитайте: stackoverflow.com/questions/13461027/   -  person Jules    schedule 30.10.2018
comment
@Jules Спасибо, удалил дополнительный вопрос.   -  person Reizo    schedule 30.10.2018


Ответы (1)


Разница между «рассматривается» и «вызывается» заключается в том, что «рассматривается» означает, что функция-кандидат участвует в разрешении перегрузки, а «вызывается» означает, что она фактически выбрана как наилучшее соответствие. Явно (каламбур не предназначен) это означает, что если во время инициализации списка копирования выбран явный конструктор, это запрещено. Например, рассмотрим этот сценарий:

struct String {
  explicit String(int size);
  String(char const *value);
};

String s = { 0 };

Здесь вы используете неявное преобразование, где явный конструктор был бы более подходящим, поэтому компилятор правомерно отклоняет его. Вам нужно написать String{ 0 }, чтобы исправить код. Теперь представьте, если бы явные конструкторы не рассматривались, а первый был бы допустимым кодом. Было бы очень странно иметь явный конструктор, который ничего не делает.

person user10579690    schedule 30.10.2018
comment
Таким образом, когда явные конструкторы могли быть вызваны, первый конструктор вызывался законно, а если явные конструкторы не рассматривались, был законно вызван второй конструктор? Что, если бы первого конструктора не существовало в исходном примере, скомпилировался бы он? - person Reizo; 30.10.2018