Это ошибка gcc, конечный тип возврата не находится в контексте полного класса [class.mem]
Завершено-класс класса класса представляет собой
- тело функции,
- аргумент по умолчанию,
- noexcept-спецификатор ([кроме.spec]),
- условие контракта или
- инициализатор члена по умолчанию
Мы видим, что для преобразования из базового в базовый класс из [conv.ptr] необходим полный класс
Значение типа «указатель на cv D», где D - это полный тип класса , может быть преобразовано в значение типа «указатель на cv B».”, Где B является базовым классом D.
и [dcl.init.ref]
« cv1 T1 »является справочнымсовместим с «cv2 T2», если значение типа «указатель на cv2 T2» можно преобразовать в тип «указатель на cv1 T1» с помощью стандартной последовательности преобразования.Во всех случаях, когда эталонно-совместимые отношения двух типов используются для установления достоверности эталонной привязки, а стандартная последовательность преобразования будет некорректной, программа, для которой требуется такая привязка, неверна.
С другой стороны, тело функции находится в пределах контекста полного класса , и, следовательно, преобразование в базовое преобразование корректно сформировано.Тип возврата, включающий тип заполнителя (decltype(auto)
) , действителен , если он уже выведен до выражения, использующего его.
Для возможного обходного пути в C ++ 11 выможет использовать
auto bar() -> decltype(foo(std::declval<Base&>()))
{
return foo(*this);
}
, если вы знаете, что хотите позвонить по номеру Base
.