Это из-за § 8.5.3 5 C ++ 03:
Ссылка на тип «
cv1 T1» инициализируется выражением типа «
cv2 T2» следующим образом:
- Если выражение инициализатора
- является lvalue (но не битовым полем), а « cv1 T1» является эталонно-совместимым с « cv2 T2» или
- имеет тип класса (т. Е. T2 является типом класса) и может быть неявно преобразован в lvalue типа « cv3 T3», где « cv1 T1» является ссылкой -совместим с « cv3 T3» 92) (это преобразование выбирается путем перечисления применимых функций преобразования (13.3.1.6) и выбора наилучшего с помощью разрешения перегрузки (13.3)),
затем ссылка привязывается непосредственно к выражению инициализатора lvalue в первом случае, а ссылка привязывается к результату lvalue преобразования во втором случае. В этих случаях указывается, что ссылка привязывается напрямую к выражению инициализатора. [ Примечание: обычные преобразования lvalue-to-rvalue (4.1), массив-в-указатель (4.2) и функция-в-указатель (4.3) не нужны и поэтому подавляются, когда такие прямые привязки к lvalues сделаны. ]
- В противном случае ссылка должна быть на энергонезависимый тип const (т. Е. cv1 должно быть const).
- Если выражение инициализатора является r-значением, с T2 - типом класса, а « cv1 T1» совместимо со ссылками с « cv2 T2», ссылка связана в одном из следующих способов (выбор определяется реализацией.
- Ссылка привязана к объекту, представленному значением r (см. 3.10) или к подобъекту в этом объекте.
- Создается временный объект типа « cv1 T2» [sic], и вызывается конструктор для копирования всего объекта rvalue во временный объект. Ссылка привязана к временному или подобъекту во временном.
- В противном случае временный тип « cv1 T1» создается и инициализируется из выражения инициализатора с использованием правил инициализации нереферентной копии (8.5). Ссылка затем привязывается к временному. Если T1 связан со ссылкой на T2, cv1 должен иметь ту же квалификацию cv или большую квалификацию cv, чем cv2 ; в противном случае программа некорректна.
Выше « cv *» относится к модификаторам «const» и «volatile», а «T *» относится к именам типов. Например, const int
( cv = "const", T = "int"), const volatile std::string
( cv = "const volatile", T = "std :: string "), char*
( cv =" ", T =" char * ").
Короче говоря, rvalues разрешено связывать только с константными ссылками.
Обновление
Если ваш square
теперь возвращает void (код или это не произошло), то новая ошибка заключается в том, что operator<<(std::out&, void)
.
нет