Mycroft Holmes
2009-09-15 12:42:22 UTC
Hi everyone.
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 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)