maher
- это const char[6]
, а sam
- это const char[4]
, и оба неявно уменьшаются до const char *
, но на самом деле ни один из них не является std::string
.
В вызовах функций стандарт C ++ позволяет выполнять неявное преобразование, если есть не-1009 * конструктор целевого типа, который принимает тип фактического значения, переданного функции.
Вот что происходит, когда вы вызываете конструктор: вы передаете const char[6]
, который автоматически затухает до const char *
; тип цели std::string
, в котором есть конструктор, который принимает const char *
; такой конструктор вызывается, и конструктор Person
правильно получает его параметр std::string
.
Во втором случае этого не происходит: Person
не имеет конструктора, который принимает const char *
, а только конструктора, который принимает std::string
. Чтобы достичь нужного Person
типа, компилятор должен сначала преобразовать const char *
в std::string
, а затем вызвать конструктор Person
. Это двойное преобразование недопустимо, главным образом потому, что разрешение перегрузки превратилось бы в полный беспорядок (что уже есть) со множеством неоднозначных случаев.
Если вы хотите разрешить вызов greet
со строкой в стиле C, вы должны либо:
создать конструктор для Person
, который принимает строку в стиле C (const char *
), так что она может быть построена непосредственно из const char *
, без прохождения запрещенного дополнительного преобразования
создать еще одну перегрузку для greet
, чтобы принять std::string
.
С другой стороны, IMO более чистая альтернатива - просто оставить все как есть; звонящий просто должен написать
maher.greet(std::string("sam"));