If we look at the grammar of a member declaration it loosk something like this:
member-declaration:
function-definition ;
function-definition:
attribute-specifier-seqopt decl-specifier-seqopt declarator
virt-specifier-seqopt function-body
declarator:
noptr-declarator parameters-and-qualifiers trailing-return-type
This disallows the syntax:
struct B {
A B::*B::read();
};
Why doesn't it allow an optional nested-name-specifier :: before the function name?
The grammar does not forbid to declare entities named by nested-name-specifiers at all.
As a matter of fact, it has to - for friend declarations:
class A
{
friend void OtherNamespace::foo();
};
This is a member-declaration with the declaration specifier friend. It's covered through (bold emphasis mine):
member-declaration:
attribute-specifier-seqopt decl-specifier-seqopt member-declarator-listopt ;
And
member-declarator:
declarator virt-specifier-seqopt pure-specifieropt
Now, a declarator has the following grammar:
declarator:
ptr-declaratorptr-declarator:
noptr-declaratornoptr-declarator:
declarator-iddeclarator-id:
...opt id-expression
Finally, an id-expression is
id-expression:
qualified-id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With