Метапрограммирование шаблонов - разница между использованием Enum Hack и Static Const - PullRequest
54 голосов
/ 31 января 2010

Мне интересно, в чем разница между использованием статического const и хака enum при использовании методов метапрограммирования шаблонов.

EX: (Фибоначчи через TMP)

template< int n > struct TMPFib {
  static const int val =
    TMPFib< n-1 >::val + TMPFib< n-2 >::val;
};

template<> struct TMPFib< 1 > {
  static const int val = 1;
};

template<> struct TMPFib< 0 > {
  static const int val = 0;
};

против

template< int n > struct TMPFib {
  enum {
    val = TMPFib< n-1 >::val + TMPFib< n-2 >::val
  };
};

template<> struct TMPFib< 1 > {
  enum { val = 1 };
};

template<> struct TMPFib< 0 > {
  enum { val = 0 };
};

Зачем использовать один над другим? Я читал, что взлом enum использовался до того, как статическая константа была поддержана внутри классов, но зачем использовать сейчас?

Ответы [ 3 ]

36 голосов
/ 31 января 2010

Перечисления не являются lval, значениями статических элементов являются, и, если они передаются по ссылке, шаблон будет создан:

void f(const int&);
f(TMPFib<1>::value);

Если вы хотите делать чистые вычисления времени компиляции и т. Д., Это нежелательный побочный эффект.

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

В руководствах по буст-кодированию есть некоторые подробности и более старая тема в архивах буста относительно предмета.

12 голосов
/ 31 января 2010

Для некоторых первое может показаться менее взломанным и более естественным.Также у него есть выделенная память для себя, если вы используете класс, так что вы можете, например, взять адрес val.

Последний лучше поддерживается некоторыми старыми компиляторами.

1 голос
/ 22 сентября 2013

С другой стороны, ответ @ Georg , когда структура, содержащая статическую переменную const, определена в специализированном шаблоне, она должна быть объявлена ​​в источнике, чтобы компоновщик мог ее найти и фактически дать ему адрес, на который будет ссылаться. Это может излишне (в зависимости от желаемых эффектов) вызывать неэффективный код, особенно если вы пытаетесь создать библиотеку только с заголовками. Вы можете решить эту проблему путем преобразования значений в функции, которые возвращают значение, что также может открыть шаблоны для информации времени выполнения.

...