Устранение во время компиляции ветви if / else в C ++ - PullRequest
8 голосов
/ 27 марта 2020

В следующем примере кода оператор if зависит от параметра шаблона bool, который является константой времени компиляции. Компиляторы обрабатывают этот код по-разному:

  • MSV C завершается с ошибкой связи (что я и ожидал), потому что функция шаблона в ветви else не имеет специализации для шаблона true значение параметра (даже если оно никогда не вызывается).

  • G CC и Clang компилируются без проблем, и поведение во время выполнения является правильным. Это очевидно, потому что они оценивают оператор if во время компиляции и удаляют неиспользуемые ветви перед связыванием.

Вопрос в том, какое поведение соответствует стандарту (или это неопределенное поведение, и оба являются правильными по-своему)?

#include <iostream>

template<const bool condition>
struct Struct
{
    void print()
    {
        if (condition)
        {
            std::cout << "True\n";
        }
        else
        {
            printIfFalse();
        }
    }

private:
    void printIfFalse();
};

template <>
void Struct<false>::printIfFalse()
{
    std::cout << "False\n";
}

int main()
{
    Struct<true> withTrue{};
    withTrue.print();

    Struct<false> withFalse{};
    withFalse.print();

    return 0;
}

1 Ответ

11 голосов
/ 27 марта 2020

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

Ваша программа плохо сформирована, диагностика не требуется c требуется , поскольку вы используете odr Struct<true>::printIfFalse через экземпляр Struct<true>::print() требуется от звонка в withTrue.print();. Функция, которая используется odr за пределами отброшенного оператора , должна иметь определение в программе, см. [basi c .def.odr] / 4 , в противном случае программа неправильно сформирован, диагностика не требуется c требуется .

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

...