This question already has answers here:
Can standard container templates be instantiated with incomplete types?
(3 answers)
Closed 8 years ago.
I defined two header files.
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#include <queue>
#include <string>
//#include "token.h"
class Token;
typedef std::string TokenValue;
enum TokenType{//...};
inline void clear(std::queue<Token> tokens)
{
std::queue<Token> empty;
std::swap(tokens, empty);
}
#endif // GLOBAL_H
and token.h
#ifndef TOKEN_H
#define TOKEN_H
#include "global.h"
class Token
{
public:
Token (TokenType token_type, TokenValue token_value)
{
token_type_ = token_type;
token_value_ = token_value;
}
~Token (){}
//...
private:
TokenType token_type_;
TokenValue token_value_;
};
I use foward declaration in global.h, but i don't use the reference or pointer of class Token. I use std::queue<Token> empty; in global.h. I think this statement must need the size of Token. I can't figure out why it can compiles success. It's the problem of queue?
When you include global.hin token.h the compiler has the complete information to work. Try to include global.h in another file and you will have your compile error :-)
Related
This question already has answers here:
C++: Has Not Been Declared
(2 answers)
Closed 4 years ago.
I don't know what is going on. I included file guards in header files but still get the error.
these are my classes:
Car.h
#ifndef CAR_H
#define CAR_H
#include "Color.h"
class Car
{
public:
Car(Color a);
void printInfo();
private:
Color carColor;
};
#endif
Car.cpp
#include "Car.h"
#include <iostream>
using namespace std;
Car::Car(Color a)
: carColor(a)
{
}
void Car::printInfo() {
cout << "the car is ";
carColor.printColor();
}
Color.h
#ifndef COLOR
#define COLOR
#include "Car.h"
#include <iostream>
using namespace std;
class Color
{
public:
Color(string c);
void printColor();
private:
string colorr;
};
#endif // COLOR
Color.cpp
#include "Color.h"
Color::Color(string c)
: colorr(c)
{
}
void Color::printColor() {
cout << colorr;
}
Edit:
guys I didn't insult to anybody. imagine you wrote lots of words and stackoverflow gives you error about question and you edit but still the same and again edit and ... this happens again and again. what should I write more ?? the question is simple and short even don't need to explain it.
For starters, you should remove #include "Car.h" from Color.h.
It creates an unnecessary circular include, and the compiler hits Car(Color a) before it knows that Color is a class.
You also need to include the header <string> to output a string to cout.
Next time, maybe don't insult the people who are helping you.
I have the following header helper.h:
#ifndef ADD_H
#define ADD_H
class Helper{
public:
static float calculateSpriteSize(float imgSize, float screenSize);
};
#endif
This is my helper.cpp:
#include "block.h"
#include "helper.h"
float Helper::calculateSpriteSize(float imgSize, float screenSize)
{
return ((imgSize/screenSize)*100);
}
But, for some reason, when I call my function calculateSpriteSize on my running code by doing:
#include "header.h"
int main(void){
float h = Helper::calculateSpriteSize( 168.0f, 170.0f );
)
I get the following error:
error: incomplete type 'Helper' used in nested name specifier
Any help would be appreciated.
Block.h looks as follows:
#ifndef ADD_H
#define ADD_H
class Block{
private:
int imgID;
int life;
float price;
public:
Block();
void setImgID(int imgID);
int getImgID();
};
#endif
And block.cpp looks as follows:
#include "block.h"
Block::Block()
{
}
void Block::setImgID(int imgID)
{
this->imgID = imgID;
}
int Block::getImgID()
{
return imgID;
}
UPDATE: I added Helper to the class definition as suggested by Rakete1111. This did not fix the issue though.
UPDATE 2: Changed forward declaration to include. Added other include that was in my code in case its important.
The type introduced by forward declaration is incomplete type. But member function invoking requires the type to be complete, otherwise how does the compiler know whether the member exists or not, and its signature?
You need to include the header file.
#include "helper.h"
int main(void){
float h = Helper::calculateSpriteSize( 168.0f, 170.0f );
)
EDIT
You're using the same macro ADD_H in both "block.h" and "helper.h". It means for
#include "block.h"
#include "helper.h"
the second including would fail, the content of helper.h won't be included at all.
Change the including guard macro name to be unique, better to make it conform to the name of file name. Such as HELPER_H and BLOCK_H.
This question already has answers here:
Circular C++ Header Includes
(6 answers)
Closed 7 years ago.
Hi...
#ifndef Node_H
#define Node_H
#include <vector>
#include <stack>
#include <string>
#include <iostream>
#include "Edge.h"
#include "CongestionMap.h"
using namespace std;
class Node
{
public:
Node(){ visit = false;};
Node(int id);
~Node();
int getID();
void setLocation(int &row, int &col, GridCell *Gc);;
void displayList();
private:
int row;
int col;
int id;
bool visit;
int parrent;
int distance;
typedef vector< Edge > adjNodeList;
};
#endif
When i compile the project i get error as
project\node.h(43): error C2065: 'Edge' : undeclared identifier
project\project\node.h(43): error C2923: 'std::vector' : 'Edge' is not a valid template type argument for parameter '_Ty'...
please help me ...
Edge.h
#ifndef Edge_H
#define Edge_H
#pragma once
#include <vector>
#include <stack>
#include <string>
#include <iostream>
#include "Node.h"
using namespace std;
class Edge
{
public:
Edge() {};
Edge(Node *firstNode, Node *secNode, int inCost);
~Edge(void);
Node* getDstNode();
Node* getOrgNode();
int getCost();
private:
Node *orgNode;
Node *dstNode;
int cost;
};
#endif
As some commenters have noted, you have circular references. The code is parsed in the order it appears.
If we start in node.h, early on, it includes edge.h.
edge.h includes node.h, but that cleverly won't do anything because of the #ifdef protection, and the redundant #pragma once (they both achieve the same thing, so you might consider sticking to just one approach).
Ok, the first class definition we would encounter is that for Edge. Great, except that it refers to Node, and nobody knows what that is...because we're still in the code for edge.h that's been included into node.h.
Likely you have things happening the other way around and edge.h is being included first. The next thing that happens is that node.h is included, and it declares Node, which expects to know what Edge is, but nobody has seen that yet.
So you'll need to use forward declaration, that is in edge.h before you declare class Edge, add a line indicating what Node is:
class Node;
and conversely in node.h, provide a forward declaration for Edge. The second one is to cover the case where somebody includes node.h before they include edge.h.
As an example, if you had them both declared in the same file you would still need to do something like:
class Node; // forward declaration so that compiler knows that
// Node is a class when it gets to parsing Edge
class Edge {
...
private:
Node *orgNode;
};
class Node {
....
};
}
I have been having a lot of trouble with my headers and making sure everything is declared correctly. First off my files:
//Main.cpp
#include "Item.h"
#include "Warehouse.h"
using namespace std;
int main() {
...
}
//Item.h
#ifndef ITEM_H
#define ITEM_H
#include <string>
using namespace std;
class Item {
...
};
#endif /* ITEM_H */
//Item.cpp
#include "Item.h"
//Warehouse.h
#define WAREHOUSE_H
#ifndef ITEM_H
#define ITEM_H
using namespace std;
class Item;
class Warehouse {
...
private:
Item* array; //problem starts with this
};
#endif /* WAREHOUSE_H */
//Warehouse.cpp
#include "Warehouse.h"
#include "Item.h"
Warehouse::Warehouse() {
array = new Item[arraySize]; //and this is where I get the error
}
I am pretty sure the problem has to do with my header in Warehouse.h but every combination I try does not work. Sorry if not enough of the code is posted but I figure the problem is with the includes and declarations.
Thanks ahead of time.
edit: to clarify this is not in one file. I just wrote it like this to simplify things. Each one of the above is a separate file.
Your include guards in the header file Warehouse.h are not correct.
Instead of
//Warehouse.h
#define WAREHOUSE_H
#ifndef ITEM_H
#define ITEM_H
using namespace std;
// ...
#endif /* WAREHOUSE_H */
you want
//Warehouse.h
#ifndef WAREHOUSE_H
#define WAREHOUSE_H
using namespace std;
// ...
#endif /* WAREHOUSE_H */
With the current version the class definition in item.h is never included in Warehouse.cpp because the mixed-up include guards in Warehouse.h prevent item.h to be read due to the order of
//Warehouse.cpp
#include "Warehouse.h"
#include "Item.h" //Warehouse.cpp
#include "Warehouse.h"
#include "Item.h"
Then the compiler does not know the definition of Item at that point, hence the error.
Another thing: Do not form the habit of using namespace std in header files. This will lead to issues at some point.
Problem is not in this declaration
private:
Item* array; //problem starts with this
You may define a pointer to an incomplete type.
I think the problem is in a statement where you try to allocate an object for this pointer using operator new or to dereference the pointer.
Also I do not see any reason why you do not want to include header Item.h in header Warehouse.h instead of using elaborated name
class Item;
Perhaps it is a header problem of sorts... But this is what's happening:
The compiler is giving me an error on the line:
Queue<Email> mailbox;
This is the error:
..\EmailSystem.h:25: error: ISO C++ forbids declaration of `Queue' with no type
..\EmailSystem.h:25: error: expected `;' before '<' token
Queue.h:
#ifndef QUEUE_H_
#define QUEUE_H_
#include <string>
#include "EmailSystem.h"
...
template <class B>
class Queue {
...
};
#endif /* QUEUE_H_ */
Queue.cpp:
#include "Queue.h"
...
template class Queue<Email>;
EmailSystem.h:
#ifndef EMAILSYSTEM_H_
#define EMAILSYSTEM_H_
#include <iostream>
#include <string>
#include <vector>
#include "Queue.h"
struct Email {
...
};
struct User {
std::string name;
Queue<Email> mailbox;
};
...
#endif /* EMAILSYSTEM_H_ */
You have a circular include. Queue.h includes EmailSystem.h and EmailSystem.h includes Queue.h so the include guards make sure that the header has no effect the second time it is being included. This means if Queue.h is the first to be included then Queue will not yet be declared before it is first used in EmailSystem.h which it includes, at this point:
Queue<Email> mailbox;
I'm guessing, but I find it unlikely that your template Queue (if it really is a generic class template) needs to know about Email so you should probably remove #include "EmailSystem.h" from Queue.h to solve your issue.
You #include "EmailSystem.h" in Queue.h, before you declare class Queue. So when the compiler tries to figure out how to create struct User, it has no clue what's the Queue<Email> you're trying to use.
Note that EmailSystem.h and Queue.h include each other.