Reputation: 119
I have a beginner question regarding nested classes in c++. There are a lot of information on the internet about this but i still can't get it to work properly without compile errors. I simply want to return the inner class B from a function inside class A.
template<class T>
class A
{
public:
A();
class B
{
public:
B(){};
};
B getB();
};
template<class T>
A<T>::A(){}
template<class T>
B A<T>::getB{return B();}
When i do this i get the error "B does not name a type". I believe the solution is to use typedef class A<T>::B b_class;
, but i still end up with the same error.
Thank you!
Upvotes: 2
Views: 125
Reputation: 98338
A
is the name of a template, so A<T>
is the name of the (instantiated) class.
Thus, the full name of the nested class is A<T>::B
, but since B
depends on the template parameter T
and is a type, you must specify template A<T>::B
.
The tricky bits is that inside the declaration of A
you can refer to B
simply by using the B
name. And you can refer to the instantiation of A<T>
by using A
, using what is called the injected class name. So inside the class declaration, A
can refer both to the template and the class instantiation.
Answering your question:
template<class T>
typename A<T>::B A<T>::getB()
{
B b;
return b;
}
Note that the return type is outside the declaration of the function, so you need to use the fully qualified name.
Upvotes: 1
Reputation: 65580
template<class T>
B A<T>::getB{return B b;}
There are three issues here:
B
at the start of the declaration does not name the type A<T>::B
. You need to be explicit about it, either by using typename A<T>::B
or with a trailing return type so that B
refers to the correct name.
You don't have ()
after getB
Your syntax for creating a temporary B
is incorrect, it should be B()
or B{}
Here is a fixed version:
template<class T>
auto A<T>::getB() -> B { return B{}; }
Upvotes: 1
Reputation: 39370
You need to change a few things: add parens to the function definition, qualify the outer B
with the enclosing class (A<T>::
) alongside with typename
(required because the type depends on the type of A) and change the return to actual object creation.
Here, listed in fixed source:
template<class T>
typename A<T>::B A<T>::getB() {return B();}
//^----------------------------------------------typename
// ^---------------------------------------qualification
// ^---------------------parens
// ^---------c-tor call
Upvotes: 2