Использует 'decltype' в объявлении указателя на член действительный?

Представьте себе по какой-то странной причине я пишу это:

int main()
{
    struct S
    {        
        int i;
    } var;


    int decltype(var)::* pint = &decltype(var)::i;
}

GCC, кажется, скомпилирует его, хотя Clang не удается с некоторым неопределенным сообщением об ошибке, связанным с синтаксисом.

Так что говорит об этом священная бумага ИСО - это действительно или нет?

Ответ 1

Это фактически известная ошибка в Clang.

Код действителен.

N4140 [dcl.mptr]/1:

В объявлении T D, где D имеет форму

nested-name-specifier * attribute-specifier-seq opt cv-qualifier-seq optD1

а спецификатор вложенных имен обозначает класс, а тип идентификатора в объявлении T D1 - это "производный-декларатор-тип-список T", тогда тип идентификатора D msgstr "выведенный-declarator-type-list cv-qualifier-seq pointer член класса вложенного имени-спецификатора типа T". Необязательный атрибут-спецификатор-seq (7.6.1) относится к указатель на элемент.

В этом определении нас интересует спецификатор вложенных имен и он определен в [expr.prim.general]/8 как (основное внимание):

вложен имя спецификатор:

::имя-типа ::
namespace-name ::
decltype-specifier ::
Идентификатор идентификатора вложенного имени ::
inest-name-specifier template opt simple-template-id ::