C++: 'set' and 'vector' "undeclared despite #include statements - c++

I am using Netbeans 7.1 on Ubuntu 11.04.
The following call
set< Triangle > V;
gives the error message
error: ‘set’ was not declared in this scope
and the following call
vector< Triangle > ans;
gives the error message
error: ‘vector’ was not declared in this scope
This despite my having
#include <vector>
#include <set>
#include <map>
at the beginning of the C++ file.
At help resolving this would be greatly appreciated.
Peter.

Vectors Sets and map are part of the c++ Standard Library so you need to call vector/set/map with
std::vector< Triangle > ans;
or add
using namespace std;
after the include statements.

you forgot about namespace std :
std::set< Triangle > V;
std::vector< Triangle > V;

They live in the std namespace. So, either fully quality the types (std::vector) or use a using statement (using namespace std;).
The latter option pollutes the global namespace. Never do that in a header file (otherwise the entire namespace is imported when you include the header) and only do it in your implementation file if you know that it isn't going to cause any collisions.
#include <vector>
int main(...) {
vector v; // no worky
std::vector v; // ok!
}

Related

c++17 error message: "reference to non-static member function must be called" when using a macro on a vector

I'm learning c++ and was playing around with macros. I tried defining push_back as pub, and it gave me this error:
error: reference to non-static member function must be called
vect.pub(1);
Here's my code:
#include <vector>
using namespace std;
typedef vector<int> vi;
#define pub push_back;
int main(){
vi vect;
vect.pub(1);
}
When I didn't use the #define and just wrote push_back, there was no error messages.
What exactly changed when I used the macro?
#define pub push_back;
//...
vect.pub(1);
This expands to the following, which is invalid syntax due to the extra ;.
vect.push_back;(1);
So drop the ; and #define pub push_back.
You should not put ';' for macro.
#include <vector>
using namespace std;
typedef vector<int> vi;
#define pub push_back
int main(){
vi vect;
vect.pub(1);
}
I'm learning c++ and was playing around with macros.
Stop. push_back is at most 6 extra keystrokes. Code is meant to be read by humans. You can't find pub in documentation, but you can find push_back.
Similarly using namespace std; is a terrible habit. There are loads of names that you don't realise you've just imported into the global namespace there.

'list' was not declared in this scope

I am new to c++, and I am trying to get a basic program to initialize a list of short unsigned integers. I am compiling and running using scygwin and g++.
Below is the code in the .cpp file:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <typeinfo>
using namespace std;
int main (int argc, char* argv[]) {
list<int> events;
return 0;
}
which I run by typing the following command into cygwin terminal:
$ g++ -o test.out test.cpp
However, I get the following compilation errors:
test.cpp: In function ‘int main(int, char**)’: test.cpp:16:1: error:
‘list’ was not declared in this scope list events;
^
test.cpp:16:6: error: expected primary-expression before ‘int’
list events;
^
I am confused about why list is not in the scope, since I am using namespace std? I found a similar question asked about this on a c++ forum, but my problem would be resolved with that. Anyone know what the problem is here?
-Paul
using namespace std; doesn't add any functionality to your code. It just means you don't have to type std:: when referencing things in the std namespace, like std::list.
To actually include the code base for std::list into your program, you need to add:
#include <list>
When in doubt about this kind of thing, doing a google search for cpp reference list will turn up a page like this where you can see: Defined in header <list> at the top.
Here's another question about using namespace std; that may prove useful and why you shouldn't use it. I'll add a little bit to perhaps explain namespaces.
It is common in C++ programs to organize functions into classes and namespaces. Imagine you wrote your own list class to handle certain scenarios. In order to prevent naming conflicts you would put it in a different namespace than std.
namespace MyApp {
class list;
void sort(list&);
}
For the majority of a large code base you might still prefer to use std::list but you need MyApp::list for some things. Using namespaces you can cluster your code and prevent naming conflicts for similar functionality.
Summary
using namespace std; makes it so that if you reference a function or class not in the global namespace it looks for it in the std namespace.
#include <list> actually inserts prototypes (information about how to access the code) in your source file during the preprocessor stage.

The ordering of namespace reference and includes affects compilation results

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.

C++ error: 'unordered_map' does not name a type

I am doing everything correctly as far as I can tell and I have gotten the error message:
error: 'unordered_map' does not name a type
error: 'mymap' does not name a type
In my code, I have:
#include <unordered_map>
using namespace std;
//global variable
unordered_map<string,int> mymap;
mymap.reserve(7000);
void main {
return;
}
I don't see what can be missing here....
EDIT: when I update my declaration to
std::tr1::unordered_map<string,int> mymap;
I an able to eliminate the first error, but when I try to reserve, I still get the second error message.
EDIT2: As pointed out below, reserve must go into main and I need to compile with flag
-std=c++0x
However, there still appear to be errors related to unordered_map, namely:
error: 'class std::tr1::unordered_map<std::basic_string<char>, int>' has no member named 'reserve'
Compile with g++ -std=c++11 (my gcc version is gcc 4.7.2) AND
#include <unordered_map>
#include <string>
using namespace std;
//global variable
unordered_map<string,int> mymap;
int main() {
mymap.reserve(7000); // <-- try putting it here
return 0;
}
If you want to support <unordered_map> for versions older than c++11 use
#include<tr1/unordered_map> and declare your maps in the form :- std::tr1::unordered_map<type1, type2> mymap
which will use the technical report 1 extension for backward compatibility.
You can't execute arbitrary expressions at global scope, so you should put
mymap.reserve(7000);
inside main.
This is also true for other STL containers like map and vector.

C++ can't create vector

This is weird. I created a vector just fine in one class but can't create it in another class. He's a representation of what I have:
main.h
#include <Windows.h>
#include <ShellAPI.h>
#include <vector>
#include <string>
#include <iostream>
#include "taco.h"
class MyClass
{
public:
int someint;
vector<int> myOrder;
};
taco.h
#include <vector>
class OtherClass
{
public:
vector<int> otherOrder;
};
And I get compile errors regarding the vector declaration in taco.h:
error C2143: syntax error : missing ';' before '<'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2238: unexpected token(s) preceding ';'
What am I missing here? I can uncomment out that second vector declaration and it compiles fine.
Try:
std::vector<int> otherOrder;
vector is part of the std namespace. This means that whenever you use a vector in a header file, you should include the std:: prefix.
The reason that you can sometimes get away with forgetting it is that some included files may have using namespace std; in them, allowing you to leave off the prefix. However, you should avoid the using keyword in header files, for it will pollute the namespace of any files that include it.
For a more detailed explanation of the dangers of using namespace ..., see this thread.
Try std::vector<int>. You're supposed to use the namespace --- I'm assuming you have
using namespace std;
in the main.h someplace. There's a lot of talk on SO as to why using using is bad practice ; I'd recommend that you check it out.
All C++ standard library objects live in the std namespace. Try
class MyClass
{
public:
int someint;
std::vector<int> myOrder;
// ^^^^^
};
std::vector<int> ?