One of the major reasons that we have to #include header files in header files is because we cannot forward declare enums. Witness the fact that LColor.h has the greatest number of dependencies in the entire project. And all because LColor::color is passed as an argument to functions.
I would like to propose the use of a template class Enum template <typename T> struct Enum { Enum(T val) : val_(val) {}; bool operator==(Enum const & other) const { return val_ == other.val_; } private: T val_; }; template <typename T> bool operator!=(Enum<T> const & lhs, Enum<T> const & rhs) { return !(lhs == rhs); } This template will allow enums to be 'forward declared', so: struct LColor { enum color { RED, BLACK }; }; struct EnumLColor : Enum<LColor::Color> { EnumLColor(LColor::Color val) : Enum<LColor::Color>(val) {} }; It is EnumLColor that can be forward declared. It can be used as if it were the enum itself: class EnumLColor; bool compare(EnumLColor lhs, EnumLColor rhs); int main() { LColor::color red = Foo::RED; LColor::color black = LColor::BLACK; LColor::color test = LColor::RED; std::cout << compare(red, black) << ' ' << (test == red) << std::endl; return 0; } bool compare(EnumLColor const & lhs, EnumLColor rhs) { return lhs == rhs; } Attached is the working source code. Thoughts? Angus
#include <iostream> template <typename T> struct Enum { Enum(T val) : val_(val) {}; bool operator==(Enum const & other) const { return val_ == other.val_; } private: T val_; }; template <typename T> bool operator!=(Enum<T> const & lhs, Enum<T> const & rhs) { return !(lhs == rhs); } // Forward declaration class EnumLColor; bool compare(EnumLColor const & lhs, EnumLColor rhs); class LColor { public: enum color { RED, BLACK }; }; struct EnumLColor : Enum<LColor::color> { EnumLColor(LColor::color val) : Enum<LColor::color>(val) {} }; int main() { LColor::color red = LColor::RED; LColor::color black = LColor::BLACK; LColor::color test = LColor::RED; // test = black; std::cout << compare(red, black) << ' ' << compare(test, red) << std::endl; return 0; } bool compare(EnumLColor const & lhs, EnumLColor rhs) { return lhs == rhs; }