Proposed resolution (10/00): Change the grammar in 9.2.9.5 [dcl.type.elab] to read
elaborated-type-specifier:
and change the forms allowed in paragraph 1 to
class-key ::opt
nested-name-specifieropt identifier
class-key ::opt
nested-name-specifieropt
templateopt template-id
enum ::opt
nested-name-specifieropt identifier
typename ::opt nested-name-specifier
identifier
typename ::opt nested-name-specifier
templateopt template-id
class-key identifier ;
friend class-key ::opt identifier
;
friend class-key ::opt template-id
;
friend class-key ::opt
nested-name-specifier identifier ;
friend class-key ::opt
nested-name-specifier templateopt
template-id ;
I can't find the answer to the following in the standard. Does
anybody have a reference? The syntax for elaborated type specifier is
[Footnote: The class-key of the
elaborated-type-specifier is required.
—end footnote] An additional problem was reported via comp.std.c++ : the
grammar does not allow the following example:
elaborated-type-specifier:
Which does not allow the production
If an elaborated-type-specifier is the sole constituent of a declaration,
the declaration is ill-formed unless it is an explicit specialization
(13.9.4 [temp.expl.spec]
),
an explicit instantiation
(13.9.3 [temp.explicit]
) or it has one of the following
forms:
class-key identifier ;
friend class-key identifier ;
friend class-key :: identifier ;
friend class-key nested-name-specifier identifier ;
class foo<int> // foo is a template
On the other hand, a friend declaration seems to require this production,
An elaborated-type-specifier shall be used in a
friend declaration for a class.*
And in 13.7.5 [temp.friend]
we find the example
[Example:
Is there some special dispensation somewhere to allow the syntax in this
context? Is there something I've missed about elaborated-type-specifier?
Is it just another bug in the standard?
template<class T> class task;
template<class T> task<T>* preempt(task<T>*);
template<class T> class task {
// ...
friend void next_time();
friend void process(task<T>*);
friend task<T>* preempt<T>(task<T>*);
template<class C> friend int func(C);
friend class task<int>;
template<class P> friend class frd;
// ...
};
namespace A{
class B{};
};
namespace B{
class A{};
class C{
friend class ::A::B;
};
};