views:

328

answers:

4

Problem fixed! Thanks a lot for the constructive suggestions!

I am unable to figure out what is the mistake in the following code. Is there something wrong with the way I am doing includes?

// This is utils.h
#ifndef UTILS_H
#define UTILS_H

#include <iostream>
#include <fstream>
#include <stack>
#include <queue>
#include <vector>
#include <list>
#include <string>
#include <algorithm>

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vii> vvii;
typedef stack<int> si;
typedef queue<int> qi;

#define tr(c,i) for(typeof((c).begin()) i = (c).begin() ; i!=(c).end() ; ++i )
#define all(c) (c).begin(),(c).end()
#define cpresent(c,x) (find(all(c),x) != (c).end())

#endif

// ==============================================================
// Below is main.cpp

#include "utils.h"

int main() {
    vi v;
}

On compiling "g++ main.cpp" I get the following error message:

utils.h:13: error: expected initializer before ‘<’ token utils.h:14: error: expected initializer before ‘<’ token utils.h:15: error: expected initializer before ‘<’ token utils.h:16: error: expected initializer before ‘<’ token utils.h:17: error: expected initializer before ‘<’ token utils.h:18: error: expected initializer before ‘<’ token main1.cpp: In function ‘int main()’: main1.cpp:4: error: ‘vi’ was not declared in this scope main1.cpp:4: error: expected `;' before ‘v’

What is wrong with this code? The utils.h used to work fine some time back when I did not have the #ifndefs in it.

+5  A: 

Those types (pair, stack, queue, vector, etc.) are in the std namespace. You either need to add using namespace std; at the top of your file (generally after all of the standard library includes) or fully qualify the type names by adding std:: in front of them.

Generally, it's better practice to fully qualify the type names than to use using namespace to avoid potential collisions between names and to make your code cleaner. You should never use using namespace std in header files.

(Along the lines of clean code, you should consider using better, longer names for your types; ii, vii, and vvii are atrocious type names).

James McNellis
+3  A: 

vector and the like are contained in the namespace std::. Do not use using namespace std; in a header file. Otherwise everyone that includes it gets all of std:: whether intended or not.

On a side note, if this is a utility header intended to be included in other files, you might wrap up those types and #define's in a namespace. Note #define's don't respect namespaces, so you'd prefix them instead:

namespace utility
{
    // ...
    typedef std::queue<int> qi;

    // most would recommend this be in CAPS
    #define utility_tr(c,i) for(typeof((c).begin()) i = (c).begin() ; i!=(c).end() ; ++i )
    // ...    
}
GMan
+1 for suggesting he put his code into a namespace; definitely a good suggestion.
James McNellis
+1  A: 

Before your typedefs, you should have using namespace std;

Also, you may wish to use a less common name than UTILS_H.

wrang-wrang
No, he shouldn't. He should fully qualify them, because this is a header file. (And because `using namespace std;` is generally bad practice)
GMan
+1  A: 

you should write

using namespace std;

before line

typedef pair<int,int> ii;

or fully qualify types of stl with std::

sergdev
For most purposes using namespace std; is sufficient. While using the std:: operator provides for better variable shadowing (especially if you work with euclidean vectors), its generally unnecessary and leads to obfuscated code.Its also worth noting, that #include<vector> is the namespace version, #include<vector.h> is not, and thus a valid alternative solution (though not one I'd recommend).
tzenes
`std::` is not an operator; `::` is an operator. `vector.h` is not part of the C++ standard.
James McNellis
@tzenes: I prefer to use std::-prefix. But, since author of question likes names like ii, vi, vii, I think that it is better to use 'using namespace std' for consistency :)
sergdev
If you can tell me what to use instead of vi that is shorter than writing vector<int> itself, but as readable as vector<int> then I would gladly use it. I don't see any reason for using typedefs other than writing less.
ajay
`IntVector` and `IntVec` are nice choices.
James McNellis