Separate enum declaration and definition in C++11 - c++

There are several questions on these forums about the inheritance of C++ enums for extending (which is actually the thing without the logic). But what about inheritance just for setting specific values?
Currently, there is something like the following in my code:
//lib_impl.h
enum class X {
a = 13, // these values are
b = 42 // implementation dependent
}
//lib.h
#include "lib_impl.h"
void some_func(X param) {
X x = X::a;
}
I just want to avoid the dependecy of the 'lib' from its implementation. Probably, something other than enums must be used for that. As even in C++11 we have the ability only to declare forward enum name, but not its enumerators:
//lib.h
enum class X { a, b } // this is both declaration and definition, unfortunately
void some_func(X param) {
X x = X::a;
}
//lib_impl.h
#include "lib.h"
enum class X { // redefenition, compilation error
a = 13,
b = 42
}
What is the best compile-time solution for such problems?
--
As it seems to be unimplementable in c++, what is the most common way to resolve such issues? Leave the dependency of the 'lib' from the 'impl' as it is? Probably, 'impl' could be split into two parts, small which will be included before the 'lib.h' and other, bigger, to be included after it. Is it ok or I need to abandon the use of enums in favor of abstract classes?

Expose an enum with nominal values (start with 0, sequential say). Inside your library, remap these values to an internal enum with implementation dependent values (say an array for speed, using the external value as index). Reverse the mapping if you export said enum values to the outside (the reverse mapping will be slower).

Related

Forward Declarations of recursive templates using Boost::Units

as i am seeking to reduce the compile times of our code, i am currently trying to reduce heavy includes in header files. For this, i am forward declaring function parameters as in this example:
// Class A.h
class B;
class A
{
...
void foo(B);
}
However, i did not find a way to forward declare our typedefinitions, that rely on boost units such as the definition of a length unit (Length.h) required as a function parameter in the file Object.h:
// Length.h
using meter_unit = boost::units::si::meter_base_unit::unit_type;
using Length = boost::units::quantity<meter_unit, double>;
BOOST_UNITS_STATIC_CONSTANT(Meter, meter_unit);
BOOST_UNITS_STATIC_CONSTANT(Meters, meter_unit)
// Object.h
#include <Length.h> // This include shall be avoided
class Position;
class Object {
...
bool isNearby(Position pos, Length distance);
}
Are there any suggestions on how i could achieve this?
What I Tried:
First Approach: I tried forward declaring the template boost::units::quantity<meter_unit, double>;
but i struggeld to define the meter_unit that contains both template class meter_base_unit and unit_type inside the namespace of meter_unit.
The meter_base_unit is defined inside boost units as below (simplified) and i guess the unit_type is defined inside the macro BOOST_TYPEOF_REGISTER_TYPE.
// Boost ... Units/Meter.hpp
namespace boost::units::si {
struct meter_base_unit : public base_unit<meter_base_unit, length_dimension, -9>
{
static std::string name() { return("meter"); }
static std::string symbol() { return("m"); }
};
}
}
BOOST_TYPEOF_REGISTER_TYPE(boost::units::si::meter_base_unit)
Is such a constellation even possible to forward declare? And if not, do alternatives exist that could have the same benefit (avoided include while still using the Boost Units Library).
Second Approach: Defining classes that inherit from the respective units such as:
class Length : public boost::units::quantity<meter_unit, double>
but the problem is, that i then have to create CTR for every possible unit that i try to initialize the Length unit with (Feet, Meter, Kilometer a.s.o), which is basically re-implementing the library.
Third Approach: Creating a class that contains only the length unit as a variable, which then leads to overloading all possible operators for that class.
I am happy for every contribution regarding my specific problem and every contribution leading to deeper understanding of template forward declarations.
Thanks in Advance
SegfaultCreator

Can two enums not have a member of similar name?

I have a situation where I need two enums to hold one member of the same name. My code is in C++, Using IAR Embeddedj Workbench IDE. The code snippet is as follows:
enum Port_e : uint32_t
{
PortA = 0,
PortB,
PortC,
PortD,
PortE,
PortF,
PortG,
PortH,
PortI,
PortJ,
PortK,
NONE
};
enum Pin_e : uint32_t
{
Pin0 = 0, Pin1, Pin2, Pin3, Pin4, Pin5, Pin6, Pin7,
Pin8, Pin9, Pin10, Pin11, Pin12, Pin13, Pin14, Pin15,NONE
};
If you notice here both enums have the last member as NONE.
This code does not compile. Gives Error as NONE is already defined.
Is there any way to make it build while keeping the name as it is?
I also do not want to change the type to "enum class" as it will break the rest of my application code.
Is there any way to make it build while keeping name as it is?
Not without changes. If you wrap Port_e and Pin_e in a namespace or class you can resolve the name collision, but that would still alter the way the enums are used.
I also do not want to change the type to "enum class" as it will break the rest of my application code.
I strongly suggest you to do that anyway, and take the time to fix your application code. enum class was designed exactly to solve this problem.
You can use class enums or nest your enums in appropriate classes or namespaces.
#include <iostream>
enum class A :uint32_t { One, Two, Three };
enum class B :uint32_t { One, Two, Three };
int main()
{
std::cout << int(A::One) << std::endl;
}
Identifiers of enumeration are names of integral constants belonging to namespace enum is declared in. Class enums changed this situation, but you cant cast from and to them implicitly. Any other approach eventually would cause ODR breakage if you would use simple enogh names. In your code it leads to ambiguity: is NONE equal to 13? Or to 16?

Map one enum to another enum

There is an existing enum
typedef enum
{
myEnum_front = 11,
myEnum_back = 19
} myEnumSides;
I want to create another enum new_myEnumSides and it's values should be mapped to the values of myEnumSides. Hence forth I would be using new_myEnumSides instead of myEnumSides.
Is the code below ok for this purpose?
typedef enum
{
new_myEnum_front = myEnumSides::myEnum_front,
new_myEnum_back = myEnumSides::myEnum_back
} new_myEnumSides;
Or is there a better way?
I can't possibly imagine why do you need to do it... If you don't need to rename the enum's values, you can just make another variable of the first one, without adding another enum (I believe this is not your case, but still have to point out this opportunity):
typedef enum
{
myEnum_front = 11,
myEnum_back = 19
} myEnumSides, new_myEnumSides;//<-- just add the new variable here
If you do want to rename it (which I believe, is your case), you should not use the :: operator, but simply write:
typedef enum
{
myEnum_front = 11,
myEnum_back = 19
} myEnumSides;
typedef enum
{
new_myEnum_front = myEnum_front,
new_myEnum_back = myEnum_back
} new_myEnumSides;
The :: operator should be used only if the enum is inside a class, structure or namespace, otherwise no :: is needed.
The only reason I can imagine you wanting to do this is to extend an existing enum and create a new one with extra values.
As enum does not offer any form of inheritance, being compile time constants and really just integers, you could do something like this, although I don't particularly recommend it..
// internalEnums.h
myEnum_front = 11,
myEnum_back = 19
// customerEnums.h
someNewValue = 20,
someOtherNewValue = 21
// Wherever you want to define your enums
typedef enum
{
#include "customerEnums.h"
} customerAccessible;
typedef enum
{
#include "internalEnums.h"
#include "customerEnums.h"
} internalUseOnly;
// Now there are two enumerations, sharing items.
customerAccessible::someNewValue // 11
customerAccessible::myEnum_front; // Doesn't exist
EDIT As per your comment, you could expose enumerations to the customer by keeping values in a header specifically for external use.
It's usually the case that you don't want to expose details of third party libraries, but an enumeration that lies there might have the exact members you need.
In that case it's beneficial to create a mapping for the third party enum, so that even if the backend library changes, you can simply provide the enumerators yourself.
The most concise way to do this, is by creating an alias:
using MyEnum = ThirdPartyEnum;
// {
// enumerator1,
// enumerator2
// }
This way, user code won't rely on third party internals,
you avoid doing conversions and even if the third party library is replaced, your users can keep using MyEnum by simply uncommenting the enumerator values (I like to keep them in comments, so users won't have to refer to third party libraries for documentation.

Is there a way to apply an action to N C++ class members in a loop over member names (probably via pre-processor)?

The problem:
I have a C++ class with gajillion (>100) members that behave nearly identically:
same type
in a function, each member has the same exact code done to it as other members, e.g. assignment from a map in a constructor where map key is same as member key
This identicality of behavior is repeated across many-many functions (>20), of course the behavior in each function is different so there's no way to factor things out.
The list of members is very fluid, with constant additions and sometimes deletions, some (but not all) driven by changing columns in a DB table.
As you can imagine, this presents a big pain-in-the-behind as far as code creation and maintenance, since to add a new member you have to add code to every function
where analogous members are used.
Example of a solution I'd like
Actual C++ code I need (say, in constructor):
MyClass::MyClass(SomeMap & map) { // construct an object from a map
intMember1 = map["intMember1"];
intMember2 = map["intMember2"];
... // Up to
intMemberN = map["intMemberN"];
}
C++ code I want to be able to write:
MyClass::MyClass(SomeMap & map) { // construct an object from a map
#FOR_EACH_WORD Label ("intMember1", "intMember2", ... "intMemberN")
$Label = map["$Label"];
#END_FOR_EACH_WORD
}
Requirements
The solution must be compatible with GCC (with Nmake as make system, if that matters).
Don't care about other compilers.
The solution can be on a pre-processor level, or something compilable. I'm fine with either one; but so far, all of my research pointed me to the conclusion that the latter is just plain out impossible in C++ (I so miss Perl now that I'm forced to do C++ !)
The solution must be to at least some extent "industry standard" (e.g. Boost is great, but a custom Perl script that Joe-Quick-Fingers created once and posted on his blog is not. Heck, I can easily write that Perl script, being much more of a Perl expert than a C++ one - I just can't get bigwigs in Software Engineering at my BigCompany to buy into using it :) )
The solution should allow me to declare a list of IDs (ideally, in only one header file instead of in every "#FOR_EACH_WORD" directive as I did in the example above)
The solution must not be limited to "create an object from a DB table" constructor. There are many functions, most of them not constructors, that need this.
A solution of "Make them all values in a single vector, and then run a 'for' loop across the vector" is an obvious one, and can not be used - the code's in a library used by many apps, the members are public, and re-writing those apps to use vector members instead of named members is out of the question, sadly.
Boost includes a great preprocessor library that you can use to generate such code:
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/cat.hpp>
typedef std::map<std::string, int> SomeMap;
class MyClass
{
public:
int intMember1, intMember2, intMember3;
MyClass(SomeMap & map)
{
#define ASSIGN(z,n,_) BOOST_PP_CAT(intMember, n) = map[ BOOST_PP_STRINGIZE(BOOST_PP_CAT(intMember, n))];
BOOST_PP_REPEAT_FROM_TO(1, 4, ASSIGN, nil)
}
};
Boost.Preprocessor proposes many convenient macros to perform such operations. Bojan Resnik already provided a solution using this library, but it assumes that every member name is constructed the same way.
Since you explicitely required the possibily to declare a list of IDs, here is a solution that should better fulfill your needs.
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
// sequence of member names (can be declared in a separate header file)
#define MEMBERS (foo)(bar)
// macro for the map example
#define GET_FROM_MAP(r, map, member) member = map[BOOST_PP_STRINGIZE(member)];
BOOST_PP_SEQ_FOR_EACH(GET_FROM_MAP, mymap, MEMBERS)
// generates
// foo = mymap["foo"]; bar = mymap["bar];
-------
//Somewhere else, we need to print all the values on the standard output:
#define PRINT(r, ostream, member) ostream << member << std::endl;
BOOST_PP_SEQ_FOR_EACH(PRINT, std::cout, MEMBERS)
As you can see, you just need to write a macro representing the pattern you want to repeat, and pass it to the BOOST_PP_SEQ_FOR_EACH macro.
You could do something like this: create an adapter class or modify the existing class to have a vector of pointers to those fields, add the addresses of all member variables in question to that vector in the class constructor, then when needed run the for-loop on that vector. This way you don't (or almost don't) change the class for external users and have a nice for-loop capability.
Of course, the obvious question is: Why do you have a class with 100 members? It doesn't really seem sane.
Assuming it is sane nevertheless -- have you looked at boost preprocessor library? I have never used it myself (as one friend used to say: doing so leads to the dark side), but from what I heard it should be the tool for the job.
Surreptitiously use perl on your own machine to create the constructor. Then ask to increase your salary since you're succesfully maintaining such a huge chunk of code.
You could use the preprocessor to define the members, and later use the same definition to access them:
#define MEMBERS\
MEMBER( int, value )\
SEP MEMBER( double, value2 )\
SEP MEMBER( std::string, value3 )\
struct FluctuatingMembers {
#define SEP ;
#define MEMBER( type, name ) type name
MEMBERS
#undef MEMBER
#undef SEP
};
.. client code:
FluctuatingMembers f = { 1,2., "valuesofstringtype" };
std::cout <<
#define SEP <<
#define MEMBER( type, name ) #name << ":" << f.##name
MEMBERS;
#undef MEMBER
#undef SEP
It worked for me, but is hard to debug.
You can also implement a visitor pattern based on pointer-to-members. After the preprocessor solution, this one turns out way more debuggeable.
struct FluctuatingMembers {
int v1;
double v2;
std::string v3;
template<typename Visitor> static void each_member( Visitor& v );
};
template<typename Visitor> void FluctuatingMembers::each_member( Visitor& v ) {
v.accept( &FluctuatingMembers::v1 );
v.accept( &FluctuatingMembers::v2 );
v.accept( &FluctuatingMembers::v3 );
}
struct Printer {
FluctuatingMembers& f;
template< typename pt_member > void accept( pt_member m ) const {
std::cout << (f::*m) << "\n";
}
};
// you can even use this approach for visiting
// multiple objects simultaneously
struct MemberComparer {
FluctuatingMembers& f1, &f2;
bool different;
MemberComparer( FluctuatingMembers& f1, FluctuatingMembers& f2 )
: f1(f1),f2(f2)
,different(false)
{}
template< typename pt_member > void accept( pt_member m ) {
if( (f1::*m) != (f2::*m) ) different = true;
}
};
... client code:
FluctuatingMembers object1 = { 1, 2.2, "value2" }
, object2 = { 1, 2.2, "valuetoo" };
Comparer compare( object1, object2 );
FluctuatingMembers::each_member( compare );
Printer pr = { object1 };
FluctuatingMembers::each_member( pr );
Why not do it at run time? (I really hate macro hackery)
What you really are asking for, in some sense, is class metadata.
So I would try something like:
class AMember{
......
};
class YourClass{
AMember member1;
AMember member2;
....
AMember memberN;
typedef AMember YourClass::* pMember_t;
struct MetaData : public std::vector<std::pair<std::string,pMember_t>>{
MetaData(){
push_back(std::make_pair(std::string("member1"),&YourClass::member1));
...
push_back(std::make_pair(std::string("memberN"),&YourClass::memberN));
}
};
static const MetaData& myMetaData() {
static const MetaData m;//initialized once
return m;
}
YourClass(const std::map<std::string,AMember>& m){
const MetaData& md = myMetaData();
for(MetaData::const_iterator i = md.begin();i!= md.end();++i){
this->*(i->second) = m[i->first];
}
}
YourClass(const std::vector<std::pair<std::string,pMember_t>>& m){
const MetaData& md = myMetaData();
for(MetaData::const_iterator i = md.begin();i!= md.end();++i){
this->*(i->second) = m[i->first];
}
}
};
(pretty sure I've got the syntax right but this is a machinery post not a code post)
RE:
in a function, each member has the same exact code done to it as other members, e.g. assignment from a map in a constructor where map key is same as member key
this is handled above.
RE:
The list of members is very fluid, with constant additions and sometimes deletions, some (but not all) driven by changing columns in a DB table.
When you add a new AMember, say newMember, all you have to do is update the MetaData constructor with an:
push_back(make_pair(std::string("newMember"),&YourClass::newMember));
RE:
This identicality of behavior is repeated across many-many functions (>20), of course the behavior in each function is different so there's no way to factor things out.
You have the machinery to apply this same idiom to build the functions
eg: setAllValuesTo(const AMember& value)
YourClass::setAllValuesTo(const AMember& value){
const MetaData& md = myMetaData();
for(MetaData::const_iterator i = md.begin();i!= md.end();++i){
this->*(i->second) = value;
}
}
If you are a tiny bit creative with function pointers or template functionals you can factor out the mutating operation and do just about anything you want to YourClass' AMember's on a collection basis. Wrap these general functions (that may take a functional or function pointer) to implement your current set of 20 public methods in the interface.
If you need more metadata just augment the codomain of the MetaData map beyond a pointer to member. (Of course the i->second above would change then)
Hope this helps.
You can do something like his:
#define DOTHAT(m) m = map[#m]
DOTHAT(member1); DOTHAT(member2);
#undef DOTHAT
That doesn't fully fit your description, but closest to it that saves you typing.
Probably what I'd look to do would be to make use of runtime polymorphism (dynamic dispatch). Make a parent class for those members with a method that does the common stuff. The members derive their class from that parent class. The ones that need a different implementation of the method implement their own. If they need the common stuff done too, then inside the method they can downcast to the base class and call its version of the method.
Then all you have to do inside your original class is call the member for each method.
I would recommend a small command-line app, written in whatever language you or your team are most proficient in.
Add some kind of template language to your source files. For something like this, you don't need to implement a full-fledged parser or anything fancy like that. Just look for an easily-identified character at the beginning of a line, and some keywords to replace.
Use the command-line app to convert the templated source files into real source files. In most build systems, this should be pretty easy to do automatically by adding a build phase, or simply telling the build system: "use MyParser.exe to handle files of type *.tmp"
Here's an example of what I'm talking about:
MyClass.tmp
MyClass::MyClass(SomeMap & map) { // construct an object from a map
▐REPLACE_EACH, LABEL, "intMember1", "intMember2, ... , "intMemberN"
▐ LABEL = map["$Label"];
}
I've used "▐" as an example, but any character that would otherwise never appear as the first character on a line is perfectly acceptable.
Now, you would treat these .tmp files as your source files, and have the actual C++ code generated automatically.
If you've ever heard the phrase "write code that writes code", this is what it means :)
There are already a lot of good answers and ideas here, but for the sake of diversity I'll present another.
In the code file for MyClass would be:
struct MemberData
{
size_t Offset;
const char* ID;
};
static const MemberData MyClassMembers[] =
{
{ offsetof(MyClass, Member1), "Member1" },
{ offsetof(MyClass, Member2), "Member2" },
{ offsetof(MyClass, Member3), "Member3" },
};
size_t GetMemberCount(void)
{
return sizeof(MyClassMembers)/sizeof(MyClassMembers[0]);
}
const char* GetMemberID(size_t i)
{
return MyClassMembers[i].ID;
}
int* GetMemberPtr(MyClass* p, size_t i) const
{
return (int*)(((char*)p) + MyClassMembers[i].Offset);
}
Which then makes it possible to write the desired constructor as:
MyClass::MyClass(SomeMap& Map)
{
for(size_t i=0; i<GetMemberCount(); ++i)
{
*GetMemberPtr(i) = Map[GetMemberID(i)];
}
}
And of course, for any other functions operating on all the members you would write similar loops.
Now there are a few issues with this technique:
Operations on members use a runtime loop as opposed to other solutions which would yield an unrolled sequence of operations.
This absolutely depends on each member having the same type. While that was allowed by OP, one should still evaluate whether or not that might change in the future. Some of the other solutions don't have this restriction.
If I remember correctly, offsetof is only defined to work on POD types by the C++ standard. In practice, I've never seen it fail. However I haven't used all the C++ compilers out there. In particular, I've never used GCC. So you would need to test this in your environment to ensure it actually works as intended.
Whether or not any of these are problems is something you'll have to evaluate against your own situation.
Now, assuming this technique is usable, there is one nice advantage. Those GetMemberX functions can be turned into public static/member functions of your class, thus providing this generic member access to more places in your code.
class MyClass
{
public:
MyClass(SomeMap& Map);
int Member1;
int Member2;
int Member3;
static size_t GetMemberCount(void);
static const char* GetMemberID(size_t i);
int* GetMemberPtr(size_t i) const;
};
And if useful, you could also add a GetMemberPtrByID function to search for a given string ID and return a pointer to the corresponding member.
One disadvantage with this idea so far is that there is a risk that a member could be added to the class but not to the MyClassMembers array. However, this technique could be combined with xtofl's macro solution so that a single list could populate both the class and the array.
changes in the header:
#define MEMBERS\
MEMBER( Member1 )\
SEP MEMBER( Member2 )\
SEP MEMBER( Member3 )\
class MyClass
{
public:
#define SEP ;
#define MEMBER( name ) int name
MEMBERS;
#undef MEMBER
#undef SEP
// other stuff, member functions, etc
};
and changes in the code file:
const MemberData MyClassMembers[] =
{
#define SEP ,
#define MEMBER( name ) { offsetof(MyClass, name), #name }
MEMBERS
#undef MEMBER
#undef SEP
};
Note: I have left error checking out of my examples here. Depending on how this would be used, you might want to ensure the array bounds are not overrun with debug mode asserts and/or release mode checks that would return NULL pointers for bad indexes. Or some use of exceptions if appropriate.
Of course, if you aren't worried about error checking the array bounds, then GetMemberPtr could actually be changed into something else that would return a reference to the member.

In C++, how can I avoid #including a header file when I need to use an enumeration?

In my C++ header files I try to use forward declarations (class MyClass;) instead of #including the class header, as recommended in many C++ coding standards (the Google C++ Style Guide is one).
Unfortunately, when I introduce enumerations, I can't do the forward declaration any more. Like this:
//// myclass1.hpp ////
class MyClass1
{
enum MyEnum1
{
Enum_A, Enum_B, Enum_C
};
};
//// myclass2.hpp ////
// I want to avoid this
#include "myclass1.hpp"
// I'd prefer to do this (forward declaration)
class MyClass1;
class MyClass2
{
// This is o.k.: I only need to forward declare MyClass1
MyClass1* ptr;
// This forces me to #include, but I don't want to!
void func( MyClass1::MyEnum1 e );
};
The best solution I can think of so far is to replace enums with member constants:
//// myclass1.hpp ////
MyClass1
{
static const int Enum_A;
static const int Enum_B;
static const int Enum_C;
};
//// myclass1.cpp ////
const int Enum_A = 1;
const int Enum_B = 2;
const int Enum_C = 3;
In this case, though, the solution seems worse than the problem.
I'm currently looking through Large Scale C++ Software Design (Lakos) and Working Effectively with Legacy Code (Feathers) for dependency breaking techniques, but I haven't found a good solution yet.
This is difficult to do nicely. Perhaps moving enums to a common header file would be a reasonable solution?
Edit: I know the question asked to avoid including a header file, but there's just no way (AFAIK) to do this. Moving enums to a separate header file at least minimises the amount of stuff in the header file you do need to include. It's certainly better than the craziness suggested in the question!
You cannot forward declare enum values - and your workaround is a step down the path to complete madness.
Are you experiencing any major compilation slowdowns caused by #including headers? If not, just #include them. Use of forward declarations is not "best practice" it is a hack.
You can use forward declarations only when you are declaring a pointer. If you are declaring a non-pointer variable, you will have to include the relevant header file.
Since an enum variable is not a pointer you can't use forward declarations. And I don't think there's an alternative solution.
C++0x's strongly typed enums can be forward declared. GCC 4.4.0 and CodeGear C++Builder 2009 support strongly typed enums.
There are a few enum-like classes floating around like the (proposed but never finalized and accepted) Boost.Enum available for download from the Boost Vault at this link. Since Boost.Enums are classes, they can be forward declared.
However, just putting enums in a separate file (as in this answer) seems the simplest, best solution (barring C++0x suport).
You can use template arguments to program against 'general' enum types. Much like this:
// enum.h
struct MyClass1 { enum e { cE1, cE2, cELast }; };
// algo.h
// precondition: tEnum contains enumerate type e
template< typename tEnum > typename tEnum::e get_second() {
return static_cast<typename tEnum::e>(1);
}
// myclass1.h
// myclass.h
template< typename tClass1 >
class MyClass2
{
tClass1 * ptr;
void func( tClass1::e e );
};
// main.cpp
#include "enum.h"
#include "algo.h"
int main(){ return get_second<Enum>(); }
I don't think (I can be proven incorrect) that you can forward declare an internal type, nor an enumeration. You will need the definition of the enclosing class to use the enum.
While most style guides enforce not including unnecessary headers, in your case the header is necessary. Other options you can consider if you really want to avoid the inclusion would be defining the enumeration outside of the class and including the header that defines the enum.
Forward declaration of enumerations has actually been proposed by the C++ standards committee. See this paper (pdf). It would certainly be a good feature!
If you are really running into compilation slowdowns because of header inclusion, the other option is to use an int instead of an enum. This is a rather unpopular approach since it degrades type safety. If you do take this approach, then I would also recommend adding code to programmatically do the bounds checking:
// in class1.h
class Class1 {
public:
enum Blah {
kFirstBlah, // this is always first
eOne = kFirstBlah,
...
kLastBlah // this is always last
};
};
// in checks.h
#include <stdexcept>
namespace check {
template <typename T, typename U>
U bounds(U lower, T value, U upper) {
U castValue = static_cast<U>(value);
if (castValue < lower || castValue >= upper) {
throw std::domain_error("check::bounds");
}
return castValue;
}
} // end check namespace
// in class2.h
class Class2 {
public:
void func(int blah);
};
// in class2.cpp
#include "class2.h"
#include "class1.h"
#include "checks.h"
void Class2::func(int blah) {
Class1::Blah blah_;
blah_ = check::bounds(Class1::kFirstBlah, blah, Class1::kLastBlah);
}
It's not the prettiest solution, but it does solve the header dependency problem by moving some of the type safety that static compilation gives you into runtime code. I've use similar approaches in the past and found that a check namespace used in this way can make the resulting code almost as readable as enum based code with very little effort.
The caveat is that you do have to make an effort to write exception-safe code which I recommend regardless of whether you adopt this approach or not ;)