I always think we should use namespace after includes, for example, we should use:
#include <vector>
using std::vector;
instead of
using std::vector;
#include <vector>
but I find the second one is OK, what confuses me is that different ordering of them causes different results.See following simple example: here are two header files and one c++ file.
// test1.h
#include <vector>
using std::vector;
#include "test2.h"
// test2.h
vector<int> v;
// test.cpp
#include "test1.h"
int main()
{
return 0;
}
Although test2.h doesn't include vector, but it compiles OK all above.
What's strange is when I swap the order of using std::vector; and #include , there happens a compile error like this:
error C2143: syntax error : missing ';' before '<'
error C2501: 'vector' : missing storage-class or type specifiers
error C2143: syntax error : missing ';' before '<'
error C2874: using-declaration causes a multiple declaration of 'vector'
I do not understand the internals, does the order of namespace and includes really matter? why so this?
It's usually a bad idea to dump names into the global namespace, where they might clash with user-declared names - especially in a header, where you force the pollution on all users of that header. Having said that:
I find the second one is OK
Only because something has already included <vector> or otherwise declared std::vector. As you can see from your later example, you get errors otherwise.
I do not understand the internals, does the order of namespace and includes really matter?
Yes, a using-declaration can only refer to names that have already been declared.
why so this?
Because that's how the language works. You can't usually use a name that hasn't been declared.
// test2.h
vector<int> v;
Header files should be self-sufficient. Writing test2.h like this requires that the user both #include <vector> and add a using declaration so that vector can be written without qualifying its name. That means the header isn't self-sufficient, because you can't simply #include it without doing a couple of other things first.
You also should not be defining variables in a header file. In a header file you should only be declaring extern variables.
#ifndef TEST2_H
#define TEST2_H
#include <vector>
extern std::vector<int> v;
#endif
Here I've also added #ifndef/#define guards so the header file can be included multiple times without error. I've also used the fully qualified std::vector with no using: it's legal, but bad practice, to put using declarations in header files.
This:
using std::vector;
#include <vector>
is not OK, unless <vector> has already been included by that file.
The important thing here is that #include does textual substituion. It simply works as if it pasted the contents of the included file over the #include directive. Header files are not compiled by themselves, they only form textual parts of the source file being compiled.
So your example works because by the time test2.h is included, the source file being compiled (test.cpp) already contains #include <vector> and using std::vector; from test1.h. And that's also why it breaks when you swap - test2.h gets included before the using declaration, so unqualified vector does not exist at the point it's used.
The preprocessor directive #include is a text replacement operation. It will read the included file and replace the #include by its contents. If you think in terms of what the operation is doing the answer should be clear.
After preprocessing main.cpp becomes:
// start test1.h
#include <vector>
using std::vector;
// start test2.h
vector<int> v;
// end test2.h
// end test1.h
int main()
{
return 0;
}
If you change the order of the using directive with respect to the inclusion of the header you will get (removing comments):
#include <vector>
vector<int> v;
using std::vector;
//...
At the point of definition of v, the using declaration has not been seen, and the compiler does not know what vector means and thus the error message.
Now back to the original assumption:
using std::vector;
#include <vector>
but I find the second one is OK
No, it is not ok. Depending on what other includes you have before hand, it might compile, but you cannot provide a using declaration before the compiler has seen the element being declared. If the two lines above compile, it means that somewhere before the first line, the expansion of the includes already brought a declaration of std::vector into this translation unit. Try to compile that by itself in a single .cpp and you will see a couple of errors.
Related
I have a multifile program, and I can't figure out why my program says that "Customers" (in the registerNewUser() function) is an undeclared identifier.
proc.h
#ifndef PROC_H
#define PROC_H
#include <iostream>
#include "const.h"
#include "customers.h"
#include <fstream>
using namespace std;
void registerNewUser(Customers cBase); // Add new user.
#endif // !PROC_H
I have included the header file (customers.h) with the Customers class also.
customers.h
#ifndef CUSTOMERS_H
#define CUSTOMERS_H
#include <iostream>
#include "const.h"
#include "proc.h"
#include "customer.h"
using namespace std;
class Customers {
private:
char* current;
List* customerList; // List for customers.
public:
Customers(); // Constructor.
~Customers(); // Destructor.
void handler(); // Customers handler/menu.
void addNew(char username[]);
};
#endif // !CUSTOMERS_H
Can anyone see what's wrong?
You have a circular include. customers.h includes proc.h so basiacally
void registerNewUser(Customers cBase);
Will get added to customers.h before the compiler has seen what a Customer is. It looks like you should just be able to remove the #include "proc.h" in customers.h and it should compile.
As stated in the comments above you should never use using namespace std; in a header file as anything that includes it now has the entire std namespace exposed. You should also get in the habit of only using it in the most narrow scope you can or drop it completely. For further reading on the use of using namespace std; see Why is “using namespace std” in C++ considered bad practice?
Basically including "customers.h" in "customers.h" wouldn't be a problem here, since you have a guard (plus point for that). Nevertheless it is not very nice.
As NathanOliver said it COULD be a problem with the order of the includes but it doesn't have to. If you include proc.h first everything is fine. If you include customers first, the compiler includes proc.h before he sees the customer class. proc then wont include customers.h (since its guard prevents it). Then he will find your function not knowing what "Customer" means. So depending on the include order of your header files it will or will not work.
If you want a hint: I normally first only include the necessary files for a forward declaration, then do a forward declaration. Then I include the files necessary files for the definition of the class (These will already know that the class exists). The complete class declaration (with member function declaration) follows. If you do it like this you can avoid many mistakes. In your case:
#ifndef CUSTOMERS_H
#define CUSTOMERS_H
class Customers;
#include "proc.h"
#include "ListTool2B.H"
using namespace std;
class Customers
{
private:
char* current;
List* customerList; // List for customers.
public:
Customers(); // Constructor.
~Customers(); // Destructor.
void handler(); // Customers handler/menu.
void addNew(char username[]);
};
#endif
This is probably a duplicate: you have proc.h including customers.h and customers.h including proc.h this will cause a circular reference, and looks like proc.h included in customers is not necessary, so you could try simply to delete this line:
#include "proc.h"
For some odd reason I am having difficulties throwing an exception in C++. I throw without catching std::invalid_argument from the stdexcept header file. I have no real intention of catching as i want the application to fail anyway if the error occurs.
It seemed to be working fine until I #included the function definition class into the namespace of the header declaration. It was added outside of the namespace prior since they are template definitions and I wanted to separate the header from its definition; however, I realized this caused a subtle issue that I did not realized until only recently.
Is their something I am missing? I am using clang btw
Project Compilation
.
.
.
.
.
Compiling CPP file TrieTest.cpp ...
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:55:30: error: unknown class name 'exception'; did you mean
'::std::exception'?
class logic_error : public exception
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/exception:60:9: note: '::std::exception' declared here
class exception
^
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:112:32: error: expected class name
class runtime_error : public exception
^
2 errors generated.
EDIT: A bit of the src
Also I compile with
clang++ -Wall -Wextra -g -std=c++11 TrieTest.cpp -o TrieTest;
"Trie.h"
#ifndef COM_WORDGAME_UTILITY_TRIE_HPP
#define COM_WORDGAME_UTILITY_TRIE_HPP
#include <string>
using std::string;
namespace wordgame_utility{
template<typename value>
class Trie{
...Trie Function Declarations
};
//The compiler may not complain initialliy however
//Templates cause visibility issues with user code and is normally defined in the header
//this is a work around
#include "Trie.cpp"
}
#endif
"Trie.cpp" head -n 8
#include "Trie.hpp"
#include <stdexcept>
using namespace wordgame_utility;
template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions
You have a cyclic include in your code.
Trie.hpp includes Trie.cpp which includes Trie.hpp. This is not meant to work in C++, where include is a literal inclusion (think, copy/pasting the included file at the point of the #include directive).
You need to define template methods into the header, or into a third file, that's all there is.
What is the effect of this cycle ? In general, poor error messages, as you can see by yourself.
In your case... let's play preprocessor ourselves:
// begin #include "Trie.hpp"
#define COM_WORDGAME_UTILITY_TRIE_HPP
// begin #include <string>
namespace std {
...
}
// end #include <string>
using std::string;
namespace wordgame_utility{
template<typename value>
class Trie{
...Trie Function Declarations
};
//The compiler may not complain initialliy however
//Templates cause visibility issues with user code
// and is normally defined in the header
//this is a work around
// begin #include "Trie.cpp"
// begin #include "Trie.hpp"
// -- empty because of the include guards --
// end #include "Trie.hpp"
// begin #include <stdexcept>
namespace std {
class logic_exception: public exception { };
}
// end #include <stdexcept>
using namespace wordgame_utility;
template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions
// end #include "Trie.cpp"
} // namespace wordgame_utility
// end #include "Trie.hpp"
As you can see, it's a mess. The combination of using #include within an open namespace and having cyclic includes is downright ugly.
Fortunately, in the (near ?) future, this will be improved if modules are adopted, which are just a much saner alternative to textual inclusion.
So I am working on a program that is due tomorrow and for some reason I keep getting this 2 errors, if I click on the first one it takes me to the iostream file and right before the _STD_BEGIN it wants me to put ";" but if I do that it messes up the file in the library so I am pretty sure I do not have to do that, the second error is in my main.cpp and it points to using namespace std; and it wants me to put a ";" before it =, if I do so the error disappears and it keeps pointing at the iostream error....
I have no idea what to do and my deadline is tomorrow.
This is my main.cpp include section with the modification to using namespace std
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <stdio.h>
#include "Package.h"
;using namespace std;
Look for a class or struct definition in Package.h that's missing its semicolon. ie.
class act
{
// yadda
} // no semicolon here
Then add the missing semicolon.
When you get a "missing ;type error on a line that follows closeley behind a bunch of#includestatements, the likely culprit is a missing;` in one of the header files. To find out which, start at the last include file, Package.h. You'll surely find a missing semicolon there. It's probably missing after a class declaration, as if you had written:
class Foo
{
}
instead of
class Foo
{
};
I'm trying to use list in c++, but I get the following error:
1>error C2143: syntax error : missing ';' before '<'
1>error C4430: missing type specifier int assumed. Note: C++ does not support default-int
1>error C2238: unexpected token(s) preceding ';'
With the following code:
#pragma once
#include "Includes.h"
class Polygon
{
public:
Polygon(void);
~Polygon(void);
void addVertice(hgeVector v);
void renderPolygon();
list<hgeVector> vertices;
};
Includes.h:
#ifndef INCLUDES
#define INCLUDES
#define safe_delete(d) if(d) { delete d; d=0; }
#define PI 3.14159
#include <stdio.h>
#include <list>
#include "\include\hge.h"
#include "\include\hgesprite.h"
#include "\include\hgefont.h"
#include "\include\hgeparticle.h"
#include "\include\hgerect.h"
#include "Car.h"
#include "HelperFunctions.h"
#include "config.h"
#include "Polygon.h"
using namespace std;
#endif
Just some general comments...
#define PI 3.14159
Please use M_PI in math.h, which is 3.141592653589793238462643.
#include "\include\hge.h"
#include "\include\hgesprite.h"
#include "\include\hgefont.h"
#include "\include\hgeparticle.h"
#include "\include\hgerect.h"
You should use forward slashes / here, and remove the leading \ before the include.
using namespace std;
Avoid this in header file. This will pollute all other users' global namespace. (Therefore, you should use std::list<hgeVector> vertices; in Polygon.h.)
The issue could be that the line list<hgeVector> vertices is being processed before using namespace std;, and so your compiler does not know what a list (without the std:: namespace qualifier) is. It's not clear to me in exactly what order these statements get processed since your two files include each other, and I don't know precisely how the non-standard #pragma once will handle this.
In any case, try qualifying list<hgeVector> as std::list<hgeVector>
Edit: Assuming #pragma once works just like include guards, then this problem will occur if some other file inlcudes includes.h, but not if some other file includes Polygon.h. If another file includes includes.h, what happens is that includes.h reaches #include <Polygon.h>, and the compiler starts processing Polygon.h. But then when #include <includes.h> is reached inside Polygon.h, nothing is effectively included since the INCLUDES guard is already defined, so you don't get the using namespace std; line before the compiler continues processing the rest of Polygons.h.
In general, try to avoid circular inclusion, and prefer forward-declarations.
I think you have circular "includes". You are including Includes.h in Polygon.h and including Polygon.h in Includes.h.
class template need a full type declaration to instantiate itself. Make sure you have included the header file where hgeVector is declared.
BTW, you have 'using namespace std‘ in your header - this is not a good practice. It will introduce unnecessary names to the current namespace.
Make sure hgeVector is defined.
You may have redefined list somewhere. Try using std::list.
Try something very simple like std::list<int>.
The answer (as Tyler McHenry pointed out) was circular inclusion!
After sorting out my includes I ended up with a compiled code like this (even without std:: infront of list:
#pragma once
#include <list>
#include "D:\Programmering\haffes\hge181\include\hge.h"
#include "D:\Programmering\haffes\hge181\include\hgevector.h"
using namespace std;
using namespace std;
class MyPolygon
{
public:
MyPolygon(void);
~MyPolygon(void);
void addVertice(hgeVector v);
void renderPolygon();
void setHotSpot(hgeVector v);
void translate(hgeVector v);
private:
list<hgeVector> vertices;
hgeVector hotSpot;
bool hotSpotUndef;
};
Thanks a bunch for all the fast and good answers!
I was doing a project for computer course on programming concepts. This project was to be completed in C++ using Object Oriented designs we learned throughout the course. Anyhow, I have two files symboltable.h and symboltable.cpp. I want to use a map as the data structure so I define it in the private section of the header file. I #include <map> in the cpp file before I #include "symboltable.h".
I get several errors from the compiler (MS VS 2008 Pro) when I go to debug/run the program the first of which is:
Error 1 error C2146: syntax error : missing ';' before identifier 'table' c:\users\jsmith\documents\visual studio 2008\projects\project2\project2\symboltable.h 22 Project2
To fix this I had to #include <map> in the header file, which to me seems strange.
Here are the relevant code files:
// symboltable.h
#include <map>
class SymbolTable {
public:
SymbolTable() {}
void insert(string variable, double value);
double lookUp(string variable);
void init(); // Added as part of the spec given in the conference area.
private:
map<string, double> table; // Our container for variables and their values.
};
and
// symboltable.cpp
#include <map>
#include <string>
#include <iostream>
using namespace std;
#include "symboltable.h"
void SymbolTable::insert(string variable, double value) {
table[variable] = value; // Creates a new map entry, if variable name already exist it overwrites last value.
}
double SymbolTable::lookUp(string variable) {
if(table.find(variable) == table.end()) // Search for the variable, find() returns a position, if thats the end then we didnt find it.
throw exception("Error: Uninitialized variable");
else
return table[variable];
}
void SymbolTable::init() {
table.clear(); // Clears the map, removes all elements.
}
My guess is that you have another file that includes the header file #include "symboltable.h". And that other source file doesn't #include <map> nor #include <string> nor has using namespace std before it includes "symboltable.h".
Check which file is being compiled when you get the error. Is it maybe a different source file than the .cpp that you mentioned? Possibly something like main.cpp?
Another way to solve your problem is to put the includes you need in your header file and use std::map instead of simply map. Also you use string which is also inside the namespace std. So that needs to be std::string. And put the missing #include <string>.
Yes, you indeed have to #include <map> in the header file.
You use map in the declaration of the class, so the compiler needs to know what this map refers to. Since the definition of it is in <map> you need to include that header before using the map template class.
You could also instead #include <map> in every source file before the #include "symboltable.h" line, but usually you would just include these kind of prerequisites in the header.