чем в b.getAbyVal() = A{7};
отличается от b.getXbyVal() = 3;
, так что первый компилируется, а второй - нет (помимо того, что типы A
и int
)?
Разница как раз в том, что одна функция возвращает тип класса, а другая функция возвращает тип POD. Временный int
, например, не может быть назначен на:
42 = x; // error
, поэтому аналогично язык запрещает назначение временному int
, возвращаемому из функции. Это не поведение по умолчанию для определяемых пользователем типов классов, поэтому присвоение временному A
компилирует:
A{} = x; // ok
изменение void operator=(A const& other) { x = other.x; }
на void operator=(A const& other) & { x = other.x; }
приводит к тому, что b.getAbyVal() = A{7};
не компилируется. Почему это так?
Добавление &
в конце называется квалификатором ссылки и позволяет определяемому пользователем классу иметь ту же семантику, что и тип POD, когда он появляется. назначить на временный. Добавление &
в конце operator=
ограничивает его использование только для l-значения (в основном, именованной переменной или ссылки, возвращаемой функцией).
A{} = x; // now error
A a;
a = x; // still ok