quiZ___
quiZ___

Reputation: 119

Simple nested class

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

Answers (3)

rodrigo
rodrigo

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

TartanLlama
TartanLlama

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

Bartek Banachewicz
Bartek Banachewicz

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

Related Questions