0

I have a large project library and a few files I added myself. One of them is a header file that contains some enums I use across the project. It looks something like this:

#ifndef MYMANYENUMS
#define MYMANYENUMS

namespace my_ns {

enum class RecType { NONE, L1, L2 };
inline int operator+ ( RecType t )
    { return underlying_type<RecType >::type(t); }

static const map<RecType, string> RecTypeMap = {
    { RecType ::NONE, "NONE" },
    { RecType ::L1, "L1" },
    { RecType ::L2, "L2" },
};
}

I include this header in a lot of other headers across the project without issues. Now I added a new header file:

#ifndef THEOTHERHEADER_H
#define THEOTHERHEADER_H

#include "MyManyEnums.h"

#endif

This file is completely empty besides what shown above. As soon as I compile I get errors:

map does not name a type
underlying_type was not declared in this scope

in my enums header file. I am pretty confused why this all of a sudden breaks. I am using qtcreator and gcc. I cant create a small example and post here that would replicate the error. I assume it must be an issue with the project structure. But I have no idea where to look and what to try so if someone can point me to potential issues that I can investigate, that would be helpful.

jerry
  • 2,581
  • 1
  • 21
  • 32
chrise
  • 4,039
  • 3
  • 39
  • 74
  • Well, since you don't include standard headers into your "enums" header, you apparently rely on other files pre-including them for you. If your "other" header is somehow included above that point - you will get these errors. – AnT stands with Russia Mar 15 '17 at 03:46

2 Answers2

2

It's likely that the other files where you #include MyManyEnums.h are including other headers beforehand that happen to define (either directly, or indirectly through other includes) those types.

I am an advocate of header files including any necessary dependencies themselves (in this case, MyManyEnums.h would #include <type_traits> and #include <map>). The other option is for any consumer of the header to include its prerequisites. Pick a paradigm and stick to it.

Edit: And as pointed out by Ken Y-N, you need to either specify the std:: namespace (preferred) or add (limited) using declarations.

jerry
  • 2,581
  • 1
  • 21
  • 32
2

The problem is twofold; first, your header file does not #include <map> to define the std::map class, and second, you use just map, not std::map, which you should NOT do in headers for precisely this reason.

Perhaps in your C++ file you have something like:

#include <type_traits>
#include <map>
using namespace std;
#include "mymanyenums.h" // Or whatever it is called.

But another file uses just:

#include "theotherheader.h"

Without having the previous three lines to set things up.

So, to conclude, use this:

#ifndef MYMANYENUMS
#define MYMANYENUMS

#include <type_traits>
#include <map>

namespace my_ns {

enum class RecType { NONE, L1, L2 };
inline int operator+ ( RecType t )
    { return std::underlying_type<RecType >::type(t); }

static const std::map<RecType, string> RecTypeMap = {
    { RecType ::NONE, "NONE" },
    { RecType ::L1, "L1" },
    { RecType ::L2, "L2" },
};
}

#endif
Community
  • 1
  • 1
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114