Ответ 1
Это была ошибка в gcc (исправлено с 2017 года -07-03), вызванные непоследовательным отношением типов возвращаемых возвратов.
Сначала обратите внимание на разницу в сообщении об ошибке между двумя попытками объявить функцию, возвращающую функцию:
using Fv = void();
Fv f1(); // error: 'f1' declared as function returning a function
auto f2() -> Fv; // error: function return type cannot be function
Первая ошибка исходит из decl.c
, обрабатывая деклараторы, а вторая намного глубже во внутренностях, от tree.c
, пытаясь построить тип функции, подготовительный к генерации кода.
Обратно-возвращаемые типы обрабатываются в decl.c 30 строк ниже вышеуказанная ошибка - слишком поздно, чтобы поймать ее с приведенной выше ошибкой кода, и он не обрабатывается отдельно.
С помощью массивов аналогичным образом с использованием типа trailing-return мы можем пропустить проверки в decl.c
, разница состоит в том, что функция-возвращающий-массив действительно действителен в терминах внутреннего представления gcc.
Обратите внимание, что вы не можете много сделать с ним; gcc не позволяет назначать, ссылаться на привязку, распадаться или передавать результат func()
другой функции:
auto a1 = func();
// error: invalid use of non-lvalue array
auto& a2 = func();
// error: invalid initialization of non-const reference of type 'int (&)[5]' from an rvalue of type 'int [5]'
auto&& a3 = func();
// error: lvalue required as unary '&' operand
Действительно, даже ваш код отклоняется в -Wpedantic
:
warning: ISO C++ forbids subscripting non-lvalue array
Наконец, используя подобную ошибку (отделители отделяются от скаляров перед обработкой возвращающих-возвращаемых типов), мы можем создать функцию с типом int const volatile()
:
int const volatile g1(); // warning: type qualifiers ignored on function return type
auto g2() -> int const volatile; // OK!!