I have a problem which is either something I have completely failed to understand, or very strange. It's probably the first one, but I have spent the whole afternoon googling with no success, so here goes...
I have a class called Schedule, which has as a member a vector of Room. However, when I compile using cmake, or even by hand, I get the following:
In file included from schedule.cpp:1:
schedule.h:13: error: ‘Room’ was not declared in this scope
schedule.h:13: error: template argument 1 is invalid
schedule.h:13: error: template argument 2 is invalid
schedule.cpp: In constructor ‘Schedule::Schedule(int, int, int)’:
schedule.cpp:12: error: ‘Room’ was not declared in this scope
schedule.cpp:12: error: expected ‘;’ before ‘r’
schedule.cpp:13: error: request for member ‘push_back’ in ‘((Schedule*)this)->Schedule::_sched’, which is of non-class type ‘int’
schedule.cpp:13: error: ‘r’ was not declared in this scope
Here are the relevant bits of code:
#include <vector>
#include "room.h"
class Schedule
{
private:
std::vector<Room> _sched; //line 13
int _ndays;
int _nrooms;
int _ntslots;
public:
Schedule();
~Schedule();
Schedule(int nrooms, int ndays, int ntslots);
};
Schedule::Schedule(int nrooms, int ndays, int ntslots):_ndays(ndays), _nrooms(nrooms),_ntslots(ntslots)
{
for (int i=0; i<nrooms;i++)
{
Room r(ndays,ntslots);
_sched.push_back(r);
}
}
In theory, g++ should compile a class before the one that includes it. There are no circular dependencies here, it's all straightforward stuff. I am completely stumped on this one,开发者_JS百科 which is what leads me to believe that I must be missing something. :-D
Edit:
The contents ofroom.h
from the comments below:
#include <vector>
#include "day.h"
class Room
{
private:
std::vector<Day> _days;
public:
Room();
Room(int ndays, int length);
~Room();
};
Even though you've omitted some important code (namely, the contents of day.h
), my psychic debugger sense tells me that you have a circular dependency in your header files:
// schedule.h
#include "room.h"
// room.h
#include "day.h"
// day.h
#include "schedule.h"
This is bad. In order to break the circular dependency, you need to figure out which file doesn't need to know the concrete implementation details of the others. This is done using forward references. For example, I can see that your definition of the Room
class doesn't actually need to know what sizeof(Day)
is for the class definition, so you can rewrite it as follows:
#include <vector>
// do NOT include day.h
class Day; // forward declaration
class Room
{
private:
std::vector<Day> _days;
public:
Room();
Room(int ndays, int length);
~Room();
};
Now room.h
doesn't depend on day.h
, breaking the circular dependency. Of course, the implementation file room.cpp
will still have to include day.h
.
It may not matter, I but I see no include guards in your headers. Shouldn't matter, but just to cover any angle...
I can't tell from your post of schedule.h/.cpp but it looks like you might have the #include "room.h" in schedule.cpp but your schedule.h is making use of class Room. #include "room.h" should be in schedule.h if this is the case.
Or you can use forward declaration in schedule.h.
In theory, g++ should compile a class before the one that includes it.
g++ should be able to compile your source files in any order it sees fit. The order it includes headers into your source is set by the order of your #include
statements.
The most likely case is that the class name is room
, and not Room
. Next likely is that the name is some other thing besides Room
. Less likely is that it is in a namespace other than the root namespace.
EDIT: Okay, if it's none of those, make sure that the room.h
that is being included is your room.h
and not some other room.h
. Nothing like editing the wrong copy of a file to waste your day.
EDIT 2: I'm assuming your header files have the usual include-once structure:
#ifndef schedule_h
#define schedule_h
// header file code goes here.
#endif
... and that you omitted it for brevity.
EDIT 3: I just copied the code you gave to a new directory, and created a dummy day.h
file with the contents:
typedef int Day;
I then used g++ -c -o schedule.o schedule.cpp
to build it and got no errors. Therefore the error is something we're not seeing.
Edit 4: Okay, sanity check time. Look at the top of room.h
and make sure it says
#ifndef room_h
and not
#ifdef room_h
What does Room.cpp look like?
Also.. I've never had any problems with this, but maybe you forgot to put an extra line at the bottom of your header file?
精彩评论