Date
2003-04-25.00:00:00
Message id
15

Content

I can't find the answer to the following in the standard. Does anybody have a reference?

The syntax for elaborated type specifier is

    elaborated-type-specifier:
      class-key ::opt nested-name-specifieropt identifier
      enum ::opt nested-name-specifieropt identifier
      typename ::opt  nested-name-specifier identifier
      typename ::opt  nested-name-specifier templateopt template-id

    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 ;
Which does not allow the production

    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.*

[Footnote: The class-key of the elaborated-type-specifier is required. —end footnote]

And in 13.7.5 [temp.friend] we find the example
[Example:
    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;
        // ...
    };
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?

An additional problem was reported via comp.std.c++: the grammar does not allow the following example:

    namespace A{
      class B{};
    };

    namespace B{
      class A{};
      class C{
	friend class ::A::B;
      };
    };