Если вы действительно столкнулись с замедлением компиляции из-за включения заголовка, другой вариант - использовать int
вместо enum
. Это довольно непопулярный подход, поскольку он снижает безопасность типов. Если вы выберете такой подход, я бы также рекомендовал добавить код для программной проверки границ:
// 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);
}
Это не самое симпатичное решение, но оно решает проблему зависимости заголовка, перенося часть безопасности типов, которую статическая компиляция дает вам в код времени выполнения. Я использовал подобные подходы в прошлом и обнаружил, что пространство имен check
, используемое таким образом, может сделать результирующий код почти таким же читабельным, как и код на основе enum
, без особых усилий.
Предостережение заключается в том, что вам необходимо приложить усилия для написания безопасного кода, который я рекомендую, независимо от того, применяете ли вы этот подход или нет;)