Как быть уверенным, что параметр будет рассматриваться как константа во время компиляции в C++?
Интересно, будут ли две следующие реализации производить одинаково с одинаковыми характеристиками независимо от того, какой компилятор я использую:
template<class T, unsigned int TSIZE> MyClass1
{
static const unsigned int size_const = 0;
public:
inline void Loop()
{
for(unsigned int i = 0; i < TSIZE; ++i) {
/* DO SOMETHING ON DATA */
}
}
T _data[TSIZE];
};
template<class T, unsigned int TSIZE> MyClass2
{
static const unsigned int size_const = TSIZE;
public:
inline void Loop()
{
for(unsigned int i = 0; i < size_const; ++i) {
/* DO SOMETHING ON DATA */
}
}
T _data[size_const];
};
В первом случае, поскольку TSIZE, используемый в цикле, является параметром шаблона, почти гарантируется, что компилятор развернет цикл при необходимости. Если цикл развернут в первом случае, будет ли он развернут во втором случае (единственное отличие состоит в том, что TSIZE хранится в статической константе)?
Большое спасибо.
2 ответа
Будет ли компилятор выполнять оптимизацию или нет, будет отличаться от того, будет ли он рассматривать значение как постоянную времени компиляции. В вашем конкретном примере, и поскольку статический const нигде не был определен, если компоновщик не жаловался, это означает, что компилятор использовал его только как выражение const (постоянная времени компиляции). Также обратите внимание, что если компилятор не рассматривал size_const
в качестве const-выражения, то строка T _data[size_const]
(Я предполагаю, что вы потеряли T
на копии) не будет компилироваться.
Любое использование odr (кроме как в качестве постоянной времени компиляции) статического члена потребовало бы определения.
По логике вещей, у компилятора достаточно информации для оптимизации, которую вы описываете, однако, будет ли он на самом деле делать это, зависит от реализации, и я не ожидаю, что он будет универсально поддерживаться.