Почему перечисление вместо статического bool? - PullRequest
3 голосов
/ 01 марта 2011

Почему в метапрограммировании шаблонов считается, что лучше использовать enum, а не static const bool?
Я читал это где-то в книге Александреску, но не могу его найти и очень хотел бы это знать.

Ответы [ 3 ]

7 голосов
/ 01 марта 2011

Стандарт C ++ (ISO / IEC 14882: 2003) разрешает использование статического константного bool только в том случае, если целочисленное постоянное выражение является обязательным .

В стандартном C ++ все члены статических данных (включая члены const) требовали определения вне своего класса.Однако в процессе стандартизации C ++ было решено снять это требование для статических константных интегральных членов.Намерение состояло в том, чтобы разрешить использование, такое как:

struct C
{
  static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition

без определения области пространства имен для N.

Тем не менее, формулировка стандарта C ++ 1998 года все еще требует определения, если используется элементв программе.Это включало элемент, появляющийся в любом месте, кроме как операнд sizeof или typeid, эффективно делающий вышеупомянутое плохо сформированным.

Это было идентифицировано как дефект, и формулировка была скорректирована, чтобы позволить такому элементу появляться вездетребуется константное выражение, не требующее определения вне класса.Сюда входят границы массивов, выражения падежа, инициализаторы статических элементов и аргументы шаблонов нетипичного типа.

struct C
{
  static const int N = 10;
  static const int U = N; // Legal per C++03
};

char data[C::N]; // Legal per C++03

template<int> struct D;

template<> struct D<C::N> {}; // Legal per C++03

Однако использование статического интегрального члена const везде, кроме случаев, когда требуется целочисленное выражение константы, требует определения.Но большинство компиляторов не будут диагностировать это нарушение:

struct C
{
  static const int N = 10;
};

int main()
{
  int i = C::N; // ill-formed, definition of C::N required
}

Эта ловушка, однако, не относится к перечислениям.

7 голосов
/ 01 марта 2011

Основная причина заключается в том, что статический тип bool - это переменная, а enum - это тип, следовательно, в случае с enum экземпляр переменной никогда не создается, и, таким образом, она гарантированно будет оценкой во время компиляции.* Также см. этот вопрос для более подробной информации.

3 голосов
/ 01 марта 2011

Это старая рекомендация, основанная на недостатках старых компиляторов, связанных с встроенной инициализацией static const примитивов внутри определений классов.static bool const - это в большинстве случаев обычный подход.

Из стандарта C ++ 03, §9.4.2 / 4:

Если элемент данных staticиз const целочисленного или const типа перечисления, его объявление в определении класса может указывать constant-initializer , который должен быть целочисленным константным выражением (5.19).В этом случае член может появляться в виде целочисленных константных выражений.Член по-прежнему должен быть определен в области имен, если он используется в программе, и определение области имен не должно содержать инициализатор .

...