Ответ 1
Func f1 = []() {};
это инициализация копирования, для которой требуется два определяемых пользователем неявного преобразования для построения f1
, первый из них - от лямбда до указателя функции, второй - от указателя функции до Func
. Только одно пользовательское неявное преобразование допускается в одной последовательности преобразований, поэтому оно терпит неудачу.
(акцент мой)
Если T - тип класса, а cv-неквалифицированная версия типа другого не является T или получена из T, или если T является неклассовым типом, а тип другого - тип класса, пользовательские последовательности преобразования который может преобразовывать из другого типа в T (или в тип, полученный из T, если T является типом класса и доступна функция преобразования), и лучший выбирается с помощью разрешения перегрузки.
а также
Неявная последовательность преобразования состоит из следующего, в следующем порядке:
1) нулевая или одна стандартная последовательность преобразования;
2) нулевое или одно пользовательское преобразование;
3) нулевая или одна стандартная последовательность преобразования.
Для f2 = []() {};
вызывается соответствующий оператор присваивания, Func
имеет одно и ожидает, что указатель функции будет аргументом; требуется только одно неявное преобразование из лямбда в указатель функции, а затем оно работает хорошо.
Func f3([]() {});
является прямой инициализацией, соответствующий конструктор пытается быть вызванным, Func
имеет один и ожидает, что указатель функции будет аргументом. Тогда это то же самое, что и f2
.
Вы можете понять суть различия между инициализацией и прямой инициализацией.
Кроме того, неявное преобразование в инициализации копии должно производить T непосредственно из инициализатора, тогда как, например, прямая инициализация ожидает неявного преобразования из инициализатора в аргумент конструктора T.