Если есть инструкция constexpr if, почему бы и другие инструкции constexpr тоже?

Есть ли какая-либо причина только if constexpr для включения в С++ 17?

Я мог бы сделать это:

template <int N>
constexpr int fib() {
    if constexpr (N == 1 || N == 2) {
        return 1;
    } else {
        return fib<N - 1>() + fib<N - 2>();
    }
}

Почему комитет С++ не рассмотрел switch constexpr тоже?

template <int N>
constexpr int fib() {
    switch constexpr (N) {
        case 1:
        case 2: return 1;
        default: return fib<N - 1>() + fib<N - 2>();
    }
}

Он выглядел намного круче с помощью switch constexpr

Или даже преждевременный цикл цикла компиляции отключается с помощью for constexpr/while constexpr без использования функции замены шаблона/рекурсивного шаблона:

constexpr void printFoo() {
    for constexpr (auto i = 0; i < 10; i++) {
        cout << fib<i>() << endl;
    }
}

Будут ли они включены в С++ 20/будущие версии С++?

Ответы

Ответ 1

if constexpr был предложен относительно близко к завершению С++ 17.

Украшения (например, switch) могли отложить его включение.

Необычные, такие как принудительное разворот цикла, несомненно, имели бы.

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

Для этого не требуется причина для не. Все происходит не всегда. Улучшение С++ - это не естественный процесс, который происходит, если кто-то не останавливает его,

Tl; dr: потому что вы не предлагали его и мужа его через стандартизацию. Начните сегодня, и это возможно в С++ 20. "Я не достоин" предлагать, это не оправдание: это работа, которую нужно делать, а не какая-то благодарность за то, что она была потрясающей. Выполняя эту работу, становится потрясающе. "Я ленивый" - оправдание, с которым я знаком.

Ответ 2

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

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

if constexpr является ценным дополнением к языку (попробуйте переписать код, чтобы не использовать его, и вы поймете, почему), и было не так сложно указать: если условие истинно, то второе подзадачу отбрасывается, в противном случае первая субстанция будет отброшена.

Напротив, switch constexpr будет создавать гораздо большие трудности в формулировке из-за больших сложностей операторов switch. (Однако вы можете попробовать.) Например, у вас есть естественное ожидание того, как это должно работать:

switch constexpr (x) {
  case 1:
    bar<x>();
    if constexpr(y) { break; }
  case 2:
    baz<x>();
}

а именно, что если x равно 1 и y истинно, то baz<x> не создается, но если x равно 1, а y - false, то baz<x> создается. Если вы хотите использовать эту семантику, вам нужно выяснить стандарт, который должен будет указать эффективную процедуру для определения того, какие именно инструкции отбрасывать (имейте в виду, что эти if и switch es могут быть произвольно вложены). Если вы не хотите эту семантику, ваш switch constexpr, вероятно, не будет более мощным, чем пучок if constexpr, но будет иметь ограничения по сравнению с обычным оператором switch.

Эти трудности еще больше возрастают с помощью for constexpr. Теперь это может стоить того. Но кто-то должен приложить усилия.

Ответ 3

Не ответ, но слишком длинный для комментария. Вы можете развернуть цикл цикла компиляции в компиляторе Intel (R) с помощью #pragma unroll.

void bar();

constexpr void foo() {
    #pragma unroll(10)
    for (auto i = 0; i < 10; i++) {
        bar();
    }
}

void baz()
{
    foo();
}

Живой пример в Godbolt, чтобы доказать разворот.