Заменяет ли заполнитель в типе конечного возврата исходный заполнитель?

G ++, кажется, принимает любую комбинацию auto а также decltype(auto) в качестве начального и конечного типов возврата:

int a;
auto f() { return (a); }                             // int
auto g() -> auto { return (a); }                     // int
auto h() -> decltype(auto) { return (a); }           // int&
decltype(auto) i() { return (a); }                   // int&
decltype(auto) j() -> auto { return (a); }           // int
decltype(auto) k() -> decltype(auto) { return (a); } // int&

Тем не менее, лязг отвергает j а также kговоря: ошибка: функция с конечным типом возврата должна указывать тип возврата «auto», а не «decltype (auto)» (демонстрация).

Какой компилятор правильный? Какое правило (auto или же decltype(auto)) следует использовать в каждом конкретном случае? И имеет ли смысл использовать тип заполнителя в задний обратный тип?

6

Решение

auto требуется при введении задний обратный тип.

§8.3.5 [dcl.fct] / 2

В декларации T D где D имеет форму

D1 ( parameter-declaration-clause ) cv-qualifier-seqвыбирать
ref-qualifierвыбирать exception-specificationвыбирать attribute-specifier-seqвыбирать trailing-return-type

и тип содержимого описатель-идентификатор в декларации T D1 является «производнымописатель-типа список T»,

T должен быть единственным Тип Спецификатор авто. […]

Смотрите также Основной выпуск 1852 для очевидного противоречия с [dcl.spec.auto] / 1.

14

Другие решения

Изменить после @Xeo конструктивные комментарии:

Похоже, что эта проблема обусловлена ​​противоречием между двумя местами проекта стандарта.

Согласно проекту стандарта § 7.1.6.4 авто спецификатор [dcl.spec.auto]:

1 auto а также decltype(auto) спецификаторы типа обозначают тип заполнителя это будет заменено позже, либо вычетом из инициализатора, либо явной спецификацией с типом конечного возврата. Авто-тип-спецификатор
также используется, чтобы показать, что лямбда — это общая лямбда.

2 Тип заполнителя может появиться с помощью объявления функции в decl-specier-seq, type-specier-seq,
ID-функции преобразования или задний обратный тип, в любом контексте, где такой декларатор действителен. Если функция
Объявление содержит конечный тип возврата (8.3.5), который определяет объявленный тип возврата функции.
Если объявленный тип возврата функции содержит тип заполнителя, тип возврата функции
выводится из операторов возврата в теле функции, если таковые имеются.

Единственная интерпретация вышеизложенного предполагает, что в Clang есть ошибка.

Тем не менее, как основной вопрос 1852 Указанное выше противоречит § 8.3.5 / 2 Функции [dcl.fct] и должен быть изменен. Статус вопроса готов, что говорит о том, что изменения были приняты.

Также, у GCC есть ошибка, о которой нужно сообщить.

3

По вопросам рекламы [email protected]