cppannotations/yo/advancedtemplates/returnnested.yo
Frank B. Brokken 06e2f86bdd Preparing 8.0.0
git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@231 f6dd340e-d3f9-0310-b409-bdd246841980
2009-07-15 11:58:17 +00:00

70 lines
2.2 KiB
Text

Consider the following example in which a nested class, that is not
depending on a template parameter, is defined within a template
class. Furthermore, the class template member tt(nested()) returns an object
of the nested class. Note that a (deprecated) in-class member implementation
is used. The reason for this will become clear shortly.
verb(
template <typename T>
class Outer
{
public:
class Nested
{};
Nested nested() const
{
return Nested();
}
};
)
The above example compiles flawlessly: within the class tt(Outer) there is
no ambiguity with respect to the meaning of tt(nested())'s return
type.
However, since it is advised to implement inline and template members
below their class interface (see section ref(DEFINLINE)), we now remove the
implementation from the interface itself, and put it below the
interface. Suddenly the compiler refuses to compile our member tt(nested()):
verb(
template <typename T>
class Outer
{
public:
class Nested
{};
Nested nested() const;
};
template <typename T>
Outer<T>::Nested Outer<T>::nested() const
{
return Nested();
}
)
The above implementation of tt(nested()) produces an error message like
quote(
em(error:)
emi(expected constructor, destructor, or type conversion) em(before
'Outer').)
In cases like these the return type (i.e., tt(Outer<T>::Nested))
refers to a em(subtype) of tt(Outer<T>) rather than to a member of
tt(Outer<T>).
As a general rule the following holds true: the keyword tt(typename) must
be used whenever a type is referred to that is a em(subtype) of a type that is
itself depending on a template type parameter.
hi(template: subtypes inside templates)
hi(class template: subtype vs. static members)
Writing tt(typename) in front of tt(Outer<T>::Nested) removes the
compilation error and therefore the correct implementation of the function
tt(nested()) becomes:
verb(
template <typename T>
typename Outer<T>::Nested Outer<T>::nested() const
{
return Nested();
}
)