Re: Template friendship to nested template class

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



Mycroft Holmes wrote:
I remember that template friendship is a hot topic, because it's not
completely clear in the standard, but we recently discovered a piece
of code like this:


template <typename T>
class OUTER
{
int private_;

template <long A, long B>
struct INNER
{
int doIt(OUTER<T> x) {return x.private_; }
};


template <long A, long B>
friend struct INNER;

public:
int exec() { return INNER<3,4>().doIt(*this); }
};


int main()
{
OUTER<double> x;
return x.exec();
}



Both VC and gcc are happy with this code, but the intel compiler is
not, and in fact Comeau reports a detailed reason for the failure:
(btw, Comeau reports 3 errors, but only the first is meaningful; the
latest intel compiler v11 only reports the 2 irrelevant errors,
omitting the first...)


Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for
ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 14: error: template nesting depth does not match
the previous
declaration of class template "OUTER<T>::INNER [with
T=double]"
Probably you are missing an EXTRA template <Param> to declare
a nested friend,
where Param is not the same id used for the enclosing class
but matches it when instantiated
friend struct INNER;
^
detected during instantiation of class "OUTER<T> [with
T=double]" at
line 29


Can somebody explain what would be the "EXTRA template <Param> to
declare a nested friend"?
(note that we don't need a fix, we already reworked the code: we took
INNER outside OUTER and made "doIt" a template member function)

I think it's because the name referred to in a 'friend' declaration is looked up (or presumed) to exist at the namespace scope. So, if you consider that your 'OUTER' template is in the global namespace, then the 'friend' declaration you have refers to the template '::INNER', and not to '::OUTER::INNER'.

I vaguely recall that in early discussions on the defects of C++ Standard there was a mention that nested classes should be granted full access to the containing class since they are, in fact, members, and by definition 'private' is for *members* and friends only. I don't know what the resolution was, however. Perhaps a careful look at the current draft Standard for C++0x would reveal what to expect. I would think that if it was determined a defect, then in the situation like yours there would be no need for a 'friend' declaration - 'INNER' already has access to 'OUTER's private members.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
.



Relevant Pages

  • Re: Circular Class Template Friendship
    ... > My issue is the syntax of declaring a friend class within ... > which the string is a fixed width that is specialized. ... it is still possible to have Name_Id_Table template ... the friend class declaration. ...
    (comp.lang.cpp)
  • Re: friend class in template
    ... This template takes 3 type parameters, the first of which is named ... The friend declaration attempts to declare the class ... the friend declaration doesn't do what the author apparently ... thought it would do (at least not on a conforming compiler). ...
    (microsoft.public.vc.language)
  • Re: Template friendship to nested template class
    ... template ... friend struct INNER; ... Both VC and gcc are happy with this code, but the intel compiler is ...
    (microsoft.public.vc.language)
  • Re: Class templates and friend function templates
    ... > expected the friend declaration to resolve to: ... > as a friend of C. ... The confusion stems from the expectation that function ... template instantiation is similar to class template ...
    (microsoft.public.vc.language)
  • Re: OK in Visual C++6.0 but not in Visual C++ .NET 2003?
    ... it's a quirk of friend declarations. ... declaration, if no matching function is already visible, then a suitable ... template unless the friend declaration names a template (template ... friend void f).. ...
    (microsoft.public.dotnet.languages.vc)