Cannot access type in base class

N

none

I have the following base class:

================== Base.h ====================================

#ifndef BASE_H
#define BASE_H

#include <vector>
#include "MyType.h"

class Base {
public:

// Types
// We use pointers for polymorphic support.
typedef std::vector<MyType*> ContainerType;

// Pure virtual
virtual ContainerType createJobs() = 0;


protected:
ContainerType jobs;

};

#endif // BASE_H


================== Sub.h ====================================

#ifndef SUB_H
#define SUB_H

#include "Base.h"

class Sub : public Base {
public:
// Types
//typedef typename Base::ContainerType ContainerType;

// Type from base class
ContainerType createJobs();

};

#endif // SUB_H

================== Sub.cpp ====================================
#include "Sub.h"

ContainerType Sub::createJobs() {
// Create some jobs and add to parent container
return this->jobs;

}

================== End ====================================



The above does not compile:

Sub.cpp:12: error: ‘ContainerType’ does not name a type

I have tried to typedef the type in the Sub.h:

typedef typename Base::ContainerType ContainerType;

but that does not help. Why is it not possible to use a type defined in the parent class?
 
N

none

none said:
I have the following base class:

================== Base.h ====================================

#ifndef BASE_H
#define BASE_H

#include <vector>
#include "MyType.h"

class Base {
public:

// Types
// We use pointers for polymorphic support.
typedef std::vector<MyType*> ContainerType;

// Pure virtual
virtual ContainerType createJobs() = 0;


protected:
ContainerType jobs;

};

#endif // BASE_H


================== Sub.h ====================================

#ifndef SUB_H
#define SUB_H

#include "Base.h"

class Sub : public Base {
public:
// Types
//typedef typename Base::ContainerType ContainerType;

// Type from base class
ContainerType createJobs();

};

#endif // SUB_H

================== Sub.cpp ====================================
#include "Sub.h"

ContainerType Sub::createJobs() {
// Create some jobs and add to parent container
return this->jobs;

}

================== End ====================================



The above does not compile:

Sub.cpp:12: error: ‘ContainerType’ does not name a type

I have tried to typedef the type in the Sub.h:

typedef typename Base::ContainerType ContainerType;

but that does not help. Why is it not possible to use a type defined in
the parent class?


A little to trigger happy here. I need to qualify the return type:

Sub::ContainerType Sub::createJobs() {

}


But is the above approach a good design or does it have some "smells" ?
 
A

Alf P. Steinbach

* none:
I have the following base class:

================== Base.h ====================================

#ifndef BASE_H
#define BASE_H

#include <vector>
#include "MyType.h"

class Base {
public:

// Types
// We use pointers for polymorphic support.
typedef std::vector<MyType*> ContainerType;

// Pure virtual
virtual ContainerType createJobs() = 0;


protected:
ContainerType jobs;

};

#endif // BASE_H


================== Sub.h ====================================

#ifndef SUB_H
#define SUB_H

#include "Base.h"

class Sub : public Base {
public:
// Types
//typedef typename Base::ContainerType ContainerType;

// Type from base class
ContainerType createJobs();

};

#endif // SUB_H

================== Sub.cpp ====================================
#include "Sub.h"

ContainerType Sub::createJobs() {

Make that

Base::ContainerType Sub::createJobs() {

or

Sub::ContainerType Sub::createJobs() {

// Create some jobs and add to parent container
return this->jobs;

}

================== End ====================================



The above does not compile:

Sub.cpp:12: error: ‘ContainerType’ does not name a type

I have tried to typedef the type in the Sub.h:

typedef typename Base::ContainerType ContainerType;

but that does not help. Why is it not possible to use a type defined in
the parent class?

It's possible, but there's a gotcha for function result specifications: at that
point the compiler doesn't yet (by the rules of the language) know that it's
dealing with a member function definition.

However, when it gets to the argument list it knows.

I've raised the issue a few times e.g. in this group, that it would be more
consistent if result types were treated like argument types, but changing the
language could possibly break a lot of existing code, namely where the result
type name is coincidentally also defined in the relevant class.


Cheers & hth.,

- Alf
 
R

Robert Fendt

ContainerType Sub::createJobs() {
// Create some jobs and add to parent container
return this->jobs;

}

The problems do not lie in the inheritance:

class Sub : public Base {
public:
// Types
typedef Base::ContainerType ContainerType; // "typename" was wrong here

// Type from base class
ContainerType createJobs();

};

================== Sub.cpp ====================================
// "ContainerType" is local to the class namespace:
Sub::ContainerType Sub::createJobs() {
// Create some jobs and add to parent container
return this->jobs;
}


Regards,
Robert
 
S

Syron

class Base {
public:
typedef std::vector<MyType*> ContainerType;
...
};
class Sub : public Base {
public:
using Base::ContainerType;
...
};

That should solve your problem.

-- Syron
 
J

James Kanze


[...]
Just curious, but what do you mean by "that does not help".
Except that it's illegal (since typename can only be used in a
template), it does introduce a symbol "ContainerType" in the
scope in which it appears.
It's possible, but there's a gotcha for function result
specifications: at that point the compiler doesn't yet (by the
rules of the language) know that it's dealing with a member
function definition.
However, when it gets to the argument list it knows.
I've raised the issue a few times e.g. in this group, that it
would be more consistent if result types were treated like
argument types, but changing the language could possibly break
a lot of existing code, namely where the result type name is
coincidentally also defined in the relevant class.

It would also break a lot of compilers, since it would mean that
name lookup of the return value couldn't occur until the
compiler knew it was dealing with a function. And without name
lookup, the compiler can't know whether the symbol is a typename
or not, which makes parsing several magnitudes more difficult.
(If it's even possible---I can't think of any off hand, but I'll
bet that allowing it would introduce some additional
ambiguities. Maybe a new and even more subtle variant of the
most embarassing parse.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top