c++language-lawyerpointer-to-memberdecltype

Is using 'decltype' in the declaration of pointer to member valid?


Imagine for some strange reason I write this:

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


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

GCC seems to compile it fine although Clang fails with some indeterminate syntax-related error message.

So what does the holy ISO paper says about this - is this valid or not?


Solution

  • This is actually a known bug in Clang.

    The code is valid.

    N4140 [dcl.mptr]/1:

    In a declaration T D where D has the form

    nested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt D1

    and the nested-name-specifier denotes a class, and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T”. The optional attribute-specifier-seq (7.6.1) appertains to the pointer-to-member.

    In this definition we are interested in nested-name-specifier, and it's defined at [expr.prim.general]/8 as (emphasis mine):

    nested-name-specifier:

    :: type-name ::
    namespace-name ::
    decltype-specifier ::
    nested-name-specifier identifier ::
    nested-name-specifier templateopt simple-template-id ::