C++ STL map typedef errors

11,312

Solution 1

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.

Solution 2

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.

Solution 3

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.

Share:
11,312
user150113
Author by

user150113

Updated on June 04, 2022

Comments

  • user150113
    user150113 almost 2 years

    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.