C++ STL map typedef errors - c++

I'm having a really nasty problem with some code that I've written. I found someone else that had the same problem on stackoverflow and I tried the solutions but none worked for me.
I typedef several common STL types that I'm using and none of the others have any problem except when I try to typedef a map.
I get a "some_file.h:83: error: expected initializer before '<' token" error when including my header in a test program.
Here's the important part of the header(some_file.h):
#ifndef SOME_FILE_H
#define SOME_FILE_H
// some syntax-correct enums+class prototypes
typedef std::string str;
typedef std::vector<Column> col_vec;
typedef col_vec::iterator col_vec_i;
typedef std::vector<Row> row_vec;
typedef row_vec::iterator row_vec_i;
typedef std::vector<str> str_vec;
typedef str_vec::iterator str_vec_i;
typedef std::vector<Object> obj_vec;
typedef obj_vec::iterator obj_vec_i;
typedef std::map<Column, Object> col_obj_map; // error occurs on this line
typedef std::pair<Column, Object> col_obj_pair;
The includes in some_file.cpp are:
#include <utility>
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <stdio.h>
#include <cc++/file.h>
#include "some_file.h"
The test file simply includes string, vector, and my file in that order. It has a main method that just does a hello world sort of thing.
The funny thing is that I quickly threw together a templated class to see where the problem was (replacing the "std::map<Column..." with "hello<Column...") and it worked without a problem.
I've already created the operator overload required by the map if you're using a class without a '<' operator.

You are getting this problem because the compiler doesn't know what a map is. It doesn't know because the map header hasn't been included yet. Your header uses the STL templates: string, vector, map, & pair. However, it doesn't define them, or have any reference to where they are defined. The reason your test file barfs on map and not on string or vector is that you include the string and vector headers before some_file.h so string and vector are defined, but map is not. If you include map's header, it will work, but then it may complain about pair (unless your particular STL implementation includes pair in map's header).
Generally, the best policy is to include the proper standard header for every type you use in your own header. So some_file.h should have, at least, these headers:
#include <string>
#include <map>
#include <utility> // header for pair
#include <vector>
The downside to this approach is that the preprocessor has to load each file every time and go through the #ifdef ... #endif conditional inclusion processing, so if you have thousands of files, and dozens of includes in each file, this could increase your compilation time significantly. However, on most projects, the added aggravation of having to manage the header inclusion manually is not worth the miniscule gain in compilation time.
That is why Scott Meyers' Effective STL book has "Always #include the proper headers" as item #48.

Is there a #include <map> somewhere in your header file?
Put that in there to at least see if it works. You should be doing that anyway.

You should shift some of those includes into your header file. These need to be placed before your typedef statements.
i.e.
#include <map>
#include <string>
#include <map>
Otherwise, anything else including some_file.h (such as your main program) won't know what they are unless it also places these includes before the #include "some_file.h" include directive in your main program source file. If you do this, the problem should go away.

As several people have pointed out, the compiler isn't finding the definition for map. Since you appear to be including the map header, there's 2 other possible causes i can think of:
Another header file called map is being loaded instead of the std map header. I think this is unlikely.
Another header is #define'ing map to be something else.
One way to check for either is get your compiler to generate the post-processed file, i.e. the source file after it has been run through the C pre-processor but before it has been compiled. You should then be able to find your offending line and see if the map type has been replaced with something else. You should also be able to search back up the file and see what header the #include opulled in.
How you generate the post-processed file is compiler dependent - check the cmd-line flags in the docs for your compiler.

Related

Classes interfering with each other on compile

I'm working on a C++ project.
I had a class with its function, then I realized some of those functions weren't related to that class but were just math functions so I decided to move them on to a namespace.
My first question is, what is the appropriate file extension for a c++ namespace?
I have a constants.h file where I plan on saving global constants, for example PI.
Right now:
#include <math.h>
const double PI = M_PI;
I have the namespace I talked about before, right now is called: specificMath.h
#include <stdlib.h>
#include "constants.h"
... more code
I have a gaussian.cpp:
#include "gaussian.h"
#include "specificMath.h"
#include <iostream>
... more code
This file includes a main function that right now does nothing, I just can't get the whole project to compile without a main...
I have a gaussian.h where I'm not including anything, is that wrong?
A third class, which has no attributes, just methods (again, is this wrong? or not pretty?). truncatedFunctions.cpp
#include "specificMath.h"
#include <stdlib.h>
#include "truncatedFunctions.h"
#include "gaussian.h"
using namespace specificMath;
And its truncatedFunctions.h where, again, I'm not including anything.
And a fourth class where I include
#include "margin.h" //Its header, where I'm not including anything
#include "gaussian.h"
#include "specificMath.h"
using namespace specificMath;
When I "make" it, it seems to compile fine, but when it gets to the linking part I get A LOT of errors saying that things on my margin.cpp class were first defined in truncatedFunctions.cpp
I am going crazy. I have no idea why this is happening, or how to solve it. I would really appreciate if somebody could help me out, and please, any extra piece of advice would be great since I am really trying to learn as much as I can with this project. Thanks!
When I "make" it, it seems to compile fine, but when it gets to the linking part I get A LOT of errors saying that things on my margin.cpp class were first defined in truncatedFunctions.cpp
Did you define your functions in your specificMath.h? You should only declare those functions.
For example, if your specificMath.h contains function definitions like
#ifndef COOL_STUFF_NSPC
#define COOL_STUFF_NSPC
#include <iostream>
namespace coolstuff{
void print(void){std::cout << "I'm declared in a header file." << std::endl;
}
#endif
and you are using including this file in several others, the linker is going crazy. Including means copying. And so you've got yourself coolstuff::print defined several times. The better way (and the only possible way when using self-written functions in many files) is splitting your code into a header and implementation as you did in gaussian.
// coolstuff.namepace.h
#ifndef COOL_STUFF_NSPC
#define COOL_STUFF_NSPC
namespace coolstuff{
void print(void);
}
#endif
When you include coolstuff.namespace.h it will only declare functions. And you can declare the same function several times.
// coolstuff.namespace.cpp
#include <iostream>
#include "cs.h"
void coolstuff::print(void){
std::cout << "Hello world!" << std::endl;
}
The .cpp file contains the implementation of your functions. Now your linker won't get irritated because there is only one implementation of coolstuff::print and not n (where n is the number of #include "cs.namespace.h" you used) ones.
My first question is, what is the appropriate file extension for a c++ namespace?
There is no standard namespace extension. Use .h/.cpp for header/implementation and a self-defined prefix, something like 'nmspc' or 'nsc'. It's up to you.
It's hard to tell whether you've done anything wrong in your code (because you didn't show any of it), but the first thing to try is to "clean" your build and rebuild all your code. If the compiler (don't know what you're using) for some reason didn't compile all your modified modules, then it's not surprising that the linker is having trouble.
My first question is, what is the appropriate file extension for a c++ namespace?
In C++, header files are usually .h or .hpp. It doesn't matter to the compiler.
#include "gaussian.h"
#include "specificMath.h"
#include <iostream>
In general, it's a good idea to #include stuff from the standard library first, followed by your own things.
I have a gaussian.h where I'm not including anything, is that wrong?
No. If you don't need to include anything, don't include anything.
First, use include guards for the headers.
#ifndef MYHEADER_H
#define MYHEADER_H
//header contents
#endif
This will prevent the same header from being included twice in the same translation unit.
Second, don't define uncosnt stuff in the headers:
double x = 0;
this will cause all translation units to export that symbol.
Declare the variable extern in your header and provide a definition for it in an implementation file.

Avoid recursive(?) #include declarations

I'm using a custom library in a c++ project, witch includes several std headers, but when i include the corresponding header in the main file, it's like i included all the headers in the custom one.
To be clear:
custom header file:
#ifndef CUSTOM_H
#define CUSTOM_H
#include <vector>
//stuff
#endif
Main.cpp:
#include <iostream>
#include "custom.h"
//here, let suppose that i do next:
vector<int> vec;
return 0;
there's no compile error, like the vector header is included, i want to avoid that, any suggestion
If custom.h's use of std::vector is an implementation detail (and not exposed in the signatures of things you define in the header), consider moving the #include <vector> to the corresponding custom.cpp file instead.
If you can't move the include out of custom.h because, say, you pass a vector in or out of a method, then it truly is part of your interface and clients of your header will need to know about it.
It is possible, but this shouldn't be done without consideration because it gives meaning to the order in which you include files, that is, you will or won't be able to compile depending on what order your #includes are in. It is generally desirable to avoid that situation.
To accomplish that, remove #include <vector> from the .h and add it to Main.cpp above where you include the custom header file. If you #include it below that, it will complain about types being undefined. Also in every file that uses the custom header file, they will have to #include <vector> first.
The problem is nearly unavoidable. If your header file needs to include another for any reason whatsoever, there's no way to "uninclude" it later.
There's one technique that can minimize the problem, the pimpl idiom or opaque pointer. By moving the implementation of a class into a private source file, you eliminate the dependencies that caused you to include the header in the first place.

where to find the definition of a external variable?

Where can I find the definition of end_of_list? I searched the whole project from eclipse, but can't find the definition. But when put end_of_list as an expression when debug, I can see it's value, just don't where from which file to find it.
#pragma once
#include <cstdlib>
#include <cassert>
#include <utility>
#include <algorithm>
#include <drizzled/memory/sql_alloc.h>
#include <drizzled/visibility.h>
namespace drizzled {
....
#define DRIZZLED_API __attribute__ ((visibility("default")))
extern DRIZZLED_API list_node end_of_list; // where to find **end_of_list**
I can see two immediate possibilities.
The Eclipse search functionality is not up to scratch, either because it's buggy (unlikely) or the actual definition of that item is held somewhere outside its scope (say, for example, you're including a header that isn't in the project).
The actual definition is not in a source file at all but possibly in an object file or library, in which case you probably shouldn't be worried about the definition - it's "hidden" for reasons of encapsulation.
Granted, these are guesses, but it's the best I can do with the information given, and I'd at least like to think that they're educated guesses :-)
If you're using "extern" to declare it in your code, then it was defined in another source file that probably came compiled in the library you're using. See:
http://drizzle.org/lcov/drizzled/sql_list.cc.gcov.html

Pulling C/C++ standard library into your project namespace, good idea?

I'm porting some open source code so that it can build on another c++ compiler. One of the difficulties and themes that seem to keep cropping up are implementation differences of the provided standard library by the compiler.
For example, one of the source files that I'm compiling includes <sys/types.h>. However, it gives me the following errors:
Error E2316 g:\Borland\BCC593\Include\sys/types.h 45: 'time_t' is not a member of 'std'
Error E2272 g:\Borland\BCC593\Include\sys/types.h 45: Identifier expected
After looking at the root cause of this I found that one of the main include headers of the project is including <sys/types.h> in this pattern:
project_source1.cpp:
#include "../TargetPlatform.h"
#include "project_config.h"
#include <windows.h>
namespace project_namespace {
#include "project_component/all.h"
// more project includes down here
// ...
}
project_component/all.h:
#ifndef INCLUDE_GUARDS
#define INCLUDE_GUARDS
#include <sys/types.h>
#include "project_header1.h"
#include "project_header2.h"
// and other headers etc..
// followed with class definitions and what not.
#endif
This is all well and good except for one problem, the <sys/types.h> is implemented something like this for the compiler I'm porting to:
<sys/types.h> trimmed to the essence:
namespace std {
typedef long time_t;
typedef short dev_t;
typedef short ino_t;
typedef short mode_t;
typedef short nlink_t;
typedef int uid_t;
typedef int gid_t;
typedef long off_t;
} // std
using std::time_t;
using std::dev_t;
using std::ino_t;
using std::mode_t;
using std::nlink_t;
using std::uid_t;
using std::gid_t;
using std::off_t;
And this is the cause of the compile error I'm seeing. Because the project is including <sys/types.h> inside its own namespace, things like time_t, off_t, dev_t etc get put into the scope project_namespace::std:: which is obviously not what's intended.
What's the best way to handle this? Keep in mind there could be other standard library headers defined in a similar fashion and not just sys/types.h. Are there any C++ idioms that's relevant or semi-related to this issue(or possibly even at odds with it due to the way this is implemented)? If so, how can it be reconciled?
Thanks
This is a bad idea. Do not do things this way. Put the namespace declarations inside each header file. Never have a #include directive inside the scope of a namespace.
Never is a strong word, and there are very rare cases in which you might want to do this. If the file you're #includeing also has #include directives, you almost certainly do not want to be doing this, even more so than if they didn't.
If you need to be able to easily rename your namespace or use the same header to declare the same symbols in several different namespaces depending on context, use the preprocessor to change the namespace name instead. That's extremely ugly to do, but much better than what you're currently doing.
One thing you can do as a quick and dirty solution to this is #include <sys/types.h> and any other system header that's included before the namespace declaration. This will cause the double-inclusion guards in the system header files to kick in and avoid declaring stuff inside the namespace.
I would say you need to change the offending code so that the standard types are no longer defined within project_namespace.
It seems to me you have two major issues: [1] you have a catch-all header in project_all.h and [2] it's #included inside namespace project_namespace. I'll address the latter first. If your project has things it wants to put in its own namespace, that's fine, but it should be done as follows:
// Foo.h
// includes go here
namespace project_namespace {
class Foo { ... }
}
// Foo.cpp
// includes go here
namespace project_namespace {
// Foo implementation goes here
}
... in other words, your classes' header and implementation files need to say what namespace the classes belong in, "self-namespacing" as it were. All your #includes are outside a namespace because the header file for each class declares the namespaces the class belongs to. This is the convention used by the standard library.
Now if you still want to use a project_all.h you can do so. Without the namespace -- because each header file will place its declarations in the namespace it wants to (or not).
But it would be better to dispense with project_all.h; instead, #include the header files individually and make the dependencies explicit. And if the response is "there are too many header files", that's probably a sign of a high degree of coupling between your components.
I realize this is probably not the answer you wanted, sorry ...

C++ style question: what to #include? [duplicate]

This question already has answers here:
Should I include every header?
(2 answers)
Closed 7 years ago.
consider this translation unit:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::size_t> mp;
mp.insert(std::make_pair("hello", 42));
}
There are two things in this translation unit that are bothering me, and they are
std::size_t
std::make_pair
I have just assumed that <cstddef> and <utility> must have been #included by <string> and <map>.
How rightful is this assumption? At least for make_pair I think there's a pretty strong guarantee because map member interfaces use std::pair. For std::size_t there is no formal guarantee but still it is very very very likely that it is available as soon as you include map or string. The stylistic question number one is Would you explicitly include <cstddef> and <utility> in this translation unit?
This part partly deals with the uncertaintly of some header being already included. However, there's the second part of the question. Suppose we have this
//f.h
#ifndef BIG_F_GUARD
#define BIG_F_GUARD
#include <string>
std::string f();
#endif
//f.cpp
#include "f.h"
std::string f()
{
std::string s;
return s;
}
Second question is: Would you explicitly #include <string> into f.cpp?
I think I made my question clear. Btw. both questions are followed by a big WHY :) Thanks.
In the first case, I probably wouldn't but I should, if I want my code to be properly portable. There's no requirement that map::size_type is size_t, so there's no necessity for <map> to include a definition of size_t. For that matter, size_t can be a type alias rather than a distinct type, so even if size_type is size_t, it needn't have been defined in <map> using that name. So as you say, it's likely but not guaranteed that <map> includes <cstddef>.
In the second case, I definitely wouldn't, because I know I don't need to. IMO a .cpp file is entitled to rely on the headers included by its corresponding .h file, since you kind of expect that if you modify the .h file you potentially need to modify the .cpp file too -- change an interface implies change its implementation, most of the time. And even if you feel I'm not entitled, I can always document that f.h includes <string>, in which case I can rely on that.
Regarding <utility>, I don't know whether <map> is allowed to define std::pair (because it needs it) without defining std::make_pair (which is from the same standard header, and for the sake of argument let's say it isn't needed to define <map>). This would be possible if the implementation's version of <utility> itself includes a bunch of other files, for different bits, and <map> just includes the bit it needs. Specific permission is given for headers to include other headers, but I don't know whether specific permission is given for headers to put things in namespace std without including the whole of the corresponding header. The thing is, in practice it is very difficult to notice that you've forgotten a standard include in these cases, because implementations don't check for you, and that's why I know that in practice I'd quite likely not do it. Luckily it should be any easy fix for anyone porting to an implementation with different header dependencies.
What I tend to do, and it's not necessarily the right thing to do, is to include all the files I need to get the module to compile. The only problem with this is that when dependencies change, you can end up with code included which isn't necessarily used. However a good compiler will normally deal with this.
There's no need to include <string> in your .cpp file however, because it's included through the header file. The contents of any included header files essentially get 'pasted' into your cpp file.
Hope this helps!
No (as long as it's something you know it has to be in there on all platforms targeted; e.g. size_t due to it being one of the parameter/return types of string stuff)
No (as the header file is your under your control and you know it's already included)
To answer your questions:
No
No
Include minimal stuff to make it compile, but no obsolete/additional dependencies that are already fulfilled
Atleast <map> is forced to include <utility> because the template for map looks like this:
namespace std {
template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T> > >
class map;
}
(Standard 23.3/1)
My two bits:
main.cpp: I would #include <cstddef> but probably not <utility> here. You are using std::size_t independent of whether it happens to be defined in the standard library headers. On the other hand, read the documentation on std::map and it is very clear that <map> must somehow define std::pair. There's no reason to #include <utility>. (This is particularly so since the connection between std::pair and is a bit of a WTF without reading the fine documentation.)
f.hh: I would grudingly #include <string> here. Normally it is better to forward declare a class rather than #include the header that defines the class if the class is only used as a reference, a pointer, or a return type. The only reason to #include <string> in f.hh is because forward declaring std::string is a bit tough.
f.cpp: I would #include <string> here. If the return type from f() was some class Foo rather than std::string, the expectation should be that the header merely forward declares Foo. The source file needs to #include the header that specifies class Foo. That the return type is std::string doesn't change this basic concept. Who knows? Some pedantically correct programmer might fix the problem in f.hh. (The problem with f.hh being that it #includes <string> when it doesn't really need to do so.)