есть ли способ заставить эту жалобу?
Вы можете использовать явно заданный по умолчанию оператор присваивания с квалификатором ref:
struct Bar {
Bar& operator=(const Bar&) & = default;
// ^
Это делает присвоение r-значения плохо сформированным, в то время как назначение l-значения остается корректным.Formed.
Обратите внимание, что объявление оператора присваивания отключает неявное присваивание перемещения, поэтому вам может потребоваться определить это также, если необходимо (также по умолчанию, и, возможно, с квалификатором rvalue ref, если необходимо).
Почему бы так не жаловаться, если Bar является временным и у него нет специального оператора =?
Поскольку неявно сгенерированные операторы присваивания не являются ref-квалифицированными.
Очевидно, что это ошибка кодирования, если ее использовать таким образом
Присвоение значения r не всегда является ошибкой.Для некоторых типов, которые должны вести себя как ссылки, присваивание значения r является естественным.Это связано с тем, что присвоение изменяет указанный объект, а не сам временный объект.
Типичным случаем использования является присвоение rvalue std::tie
(пример из cppreference ):
std::set<S> set_of_s; // S is LessThanComparable
S value{42, "Test", 3.14};
std::set<S>::iterator iter;
bool inserted;
// unpacks the return value of insert into iter and inserted
std::tie(iter, inserted) = set_of_s.insert(value);
Да, возможно, было бы лучше, если бы неявные операторы были квалифицированными, а для неквалифицированных требовалось явное объявление, учитывая, что ссылочные типы являются скорее исключительными, чем нормальными.Но язык не такой, и его изменение - это несовместимое назад изменение.