C ++ 11 — C ++ constexpr выражение выражения

У меня есть вопрос относительно следующего комментария об условных выражениях, используемых в функциях constexpr:

Ветвь условного выражения, которая не берется в функции constexpr, не оценивается. Источник: условная оценка функций

Как уже написано в источнике, вы можете иметь такие функции constexpr, как

constexpr int check(int i) {
return (0<=i && i<10) ? i : throw out_of_range();
}

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

template <int N>
constexpr int times(int y) {
return (N<0) ? 0 : y+times<N-1>(y);
}

times<5>(10);

Компиляция не удалась, потому что глубина создания шаблона превышает максимум, даже если false ветка условная берется только 4 раза. Тогда он должен принять true ответвление и возврат 0. Конечно, это можно переписать, используя enable_if или что угодно, но я только хотел бы знать следующие вещи:

  • Является ли это утверждение недействительным, когда дело доходит до оценки типа подвыражения?

  • Почему это не удается, хотя в приведенном выше утверждении утверждается, что подвыражение не оценивается? Я предполагаю, что типы должны быть оценены в любом случае (например, чтобы проверить, выполняется ли требование, чтобы обе ветви условного выражения имели один и тот же тип) и, следовательно, оно заканчивалось бесконечным созданием шаблона. Правильное предположение?

  • Есть ли место в стандарте c ++, описывающее это поведение?

2

Решение

Вы не понимаете, что значит что-то оценивать. Оценка — это то, что происходит во время выполнения (даже если это выполняется во время работы компилятора).

Создание шаблона является статический свойство вашего кода. Если ты пишешь times<N-1> Вы просите создать экземпляр этого шаблона. Неважно, если вы вызываете эту функцию или нет; вы пишете экземпляр, так что создается экземпляр.

Вот почему рекурсивное метапрограммирование обычно обрабатывает случай терминала через специализацию шаблона.

Вот почему if constexpr был добавлен в C ++ 17. Потому что он имеет право не только условно оценивать высказывания, но и условно отбрасывать заявления, делающие другую ветку эффективно не существующей. Который не то, что когда-либо существовало раньше. Это позволяет другой ветви содержать код, который в противном случае был бы статически сформирован.

Так что это будет работать:

if constexpr(N < 0) return 0 else return y+times<N-1>(y);

Второй пункт будет отброшен и, следовательно, не будет создан.

Так что утверждение верно; подвыражения оцениваются условно. Вы просто неправильно понимаете, как это относится к вашему делу.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]