Damian Vu Damian Vu - 2 months ago 10
C++ Question

error: expected class-name before '{' token - can't seem to find any circular includes

I understand that this question has been asked a few times and the usual case is because of circular includes, but I have had trouble for the past few hours trying to find out where I may have a case of circular includes. I don't think I have a point where I can forward declare anything either. I'm probably wrong, so I need some help

The assignment I am trying to complete uses two ADTs one being a Stack and the other being a Queue. These files are templated to accept any data type, but in this lab we will be using strings. Our Queue.h/.hpp is supposed to implement a QueueInterface.h, and the Stack.h/.hpp a StackInterface.h

Finally, we have to define our own error called PreconditionViolationException.h is a sub-class of std::runtime_error.

Maybe this link will help if that's not a good explanation

To possibly save some time, I'll start with a list of the files I'm using and then my Makefile.

Executive.h/.cpp, main.cpp, Node.h/.hpp PreconditionViolationException.h/.cpp Queue.h/.hpp QueueInterface.h Stack.h/.hpp StackInterface.h

BuildingExecutive: main.o Executive.o PreconditionViolationException.o
g++ -std=c++11 -g -Wall main.o PreconditionViolationException.o Executive.o -o BuildingExecutive

main.o: main.cpp
g++ -std=c++11 -g -Wall -c main.cpp

PreconditionViolationException.o: PreconditionViolationException.cpp PreconditionViolationException.h
g++ -std=c++11 -g -Wall -c PreconditionViolationException.cpp

Executive.o: Executive.cpp Executive.h Queue.hpp Queue.h Stack.hpp Stack.h Node.hpp Node.h StackInterface.h QueueInterface.h
g++ -std=c++11 -g -Wall -c Executive.cpp


This is where I have a maybe off-topic question in regards to my Makefile. My question was if I should be compiling PreconditionViolationException.o as it's own object file? I can see why I don't explicitly compile my Stack and Queue files because they are templated, but since the only files that depend on PreconditionViolationException are the templated files, does that make a difference? My Executive(which is the file that just outputs and runs the program) doesn't depend on PreconditionViolationException, it just catches any std::exception, which should catch PreconditionViolationException since std::runtime_error is a subclass of std::exception

Well if there isn't a glaring problem with my Makefile, here is basically how I tried to trace if this had any circular includes or not.

I started with my main.cpp which looks like this.

#include "Executive.h"

int main(int argc, char** argv) {
Executive exec(argv[1]);
exec.Run();
return 0;
}


This only includes Executive.h, so here is that

#ifndef EXECUTIVE_H
#define EXECUTIVE_H

#include "Queue.h"
#include "Stack.h"

class Executive {
.
. will cutout whatever isn't necessary
.
private:
Queue<std::string> Line;
Stack<std::string> Elevator;
};
#endif


This file depends on Queue.h and Stack.h so here are those

#ifndef QUEUE_H
#define QUEUE_H

#include "Node.h"
#include "QueueInterface.h"

template <typename T>
class Queue : public QueueInterface {
.
.
.
};
#endif


then

#ifndef STACK_H
#define STACK_H

#include "Node.h"
#include "StackInterface.h"

template <typename T>
class Stack : public StackInterface {
.
.
.
};


I don't think Node could be causing a problem here so here are the Interfaces

#ifndef STACKINTERFACE_H
#define STACKINTERFACE_H

#include "PreconditionViolationException.h"

template <typename T>
class StackInterface {
.
.
.
};
#endif


and

#ifndef QUEUEINTERFACE_H
#define QUEUEINTERFACE_H

#include "PreconditionViolationException.h"

template <typename T>
class QueueInterface {
.
.
.
}
#endif


Each of these include the PreconditionViolationException, because their methods can throw that exception.

#ifndef PVE_H
#define PVE_H

#include <stdexcept>
#include <string>

class PreconditionViolationException : public std::runtime_error {
.
.
.
}
#endif


Correct me if I'm wrong please, but after reading this I don't think there is anywhere other than possibly when I declare my Nodes that I could forward declare anything. Since my understanding of how a everything is compiled together isn't the best, the only things that I could think of were that my makefile wasn't right for this task, or that I have circular includes I am failing to identify.

I've spent a lot of time trying to trace and understand what is happening, so I'm hoping for something that could help me better understand what is happening.

Sorry if this is really long! Any help is appreciated!

Answer
template<class T>
class Stack : public StackInterface {

StackInterface isn't a class (it's a class template), so you can't inherit from it.

You probably meant to inherit from StackInterface<T>, and likewise for QueueInterface.