Шаблон переменной C ++. Это УБ? - PullRequest
1 голос
/ 27 июня 2019

Я создал простой шаблон переменных C ++ 14, который вычисляет факториалы (только для обучения). Тогда я хочу напечатать первые 12 факториалов.

template <int n> const int fact = n * fact<n - 1>;
template <> const int fact<0> = 1;

Если я заменю fact<12> на fact<i> в следующем фрагменте, я получу ошибку, потому что i не является константой.

int main()
{   
    for(int i = 0; i < 12; i++){
        std::cout << fact<12> << std::endl;
    }
}

Но когда я изменяю это на это, я получаю ожидаемый результат.

int main()
{   
    for(int i = 0; i < 12; i++){
        std::cout << *(&fact<12> - i) << std::endl;
    }
}

Это неопределенное поведение? Он работает, как и ожидалось, в GCC 8.3. Живой пример здесь

1 Ответ

3 голосов
/ 27 июня 2019

Это UB.Ваша арифметика указателя «работает случайно» (с UB может произойти все что угодно).

Вместо этого вы можете сделать, например:

template <std::size_t ... Is>
void print_fact(std::index_sequence<Is...>)
{
    for (int res : {fact<Is>...}) {
        std::cout << res << std::endl;
    }
}

int main()
{
    print_fact(std::make_index_sequence<12>());
}
...