//--------------------------------------------------
class A {
class B {};
friend B func(double x);
};
A::B func(double x) {return A::B();}
int main() {
func(1.2);
return 0;
}
//------------------------------------------------
This code compiles and runs on the MS Visual C++ 2008 compiler.
However, if I use a class template instead:
//--------------------------------------------------
template<typename T> class A {
class B {};
friend B func(T x);
};
template<typename T> typename A<T>::B func(T x) {return A<T>::B();}
int main() {
func(1.2); // <-- error received here
return 0;
}
//------------------------------------------------
I get an error:
error C2248: 'A<T>::B' : cannot access private class declared in class
'A<T>'.
Notice the error is in 'main', and not in the function definition, so
I don't think the problem is with the friend declaration.
So is returning an instance of a private nested class legal or not?
No, it's not legal, because the destructor for the private class needs
to run.
And the standard says explicitly that this is checked in the
context of the call.
Which doesn't explain whey the non-template version compiled.
It shouldn't, either.
--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
I don't get any problem with something like (g++ 4.3.2):
~~~
template< typename T >
class A
{
class B {};
public:
B getB() const
{ return B(); }
};
int main(int argc, char const** argv)
{
A<double>().getB();
A<int>().getB();
return 0;
}
~~~
Once I found useful to return a private class which acts as a proxy in
the implementation of an iterator. *i returns the private nested class
which implements the operator=, for an output iterator, for example.
Also, g++ 4.3.2 and online comeau compiler compile without problem the
non-template version of the friend function returning a private nested
class (first example given in the original post).