if constexpr
не предназначен для оптимизации.Компиляторы очень хорошо умеют оптимизировать ветку if (true)
или if (false)
(так как мы говорим о константных выражениях, это то, к чему это сводится).Вот пример godbolt примера в OP - вы заметите, что и gcc, и clang, даже на -O0
, не испускают ветку для простого if
.
if constexpr
означает, что только одна ветвь if
имеет экземпляр .Это чрезвычайно важно и ценно для написания шаблонов - потому что теперь мы можем фактически написать условно компилируемый код в теле одной и той же функции вместо того, чтобы писать несколько искусственных функций, просто чтобы избежать создания экземпляров.
Тем не менее, если у вас есть условие, которое является известным константным выражением - просто всегда используйте if constexpr
, независимо от того, нужна вам выгода от создания экземпляра.У такого решения нет недостатка.Читателям становится понятнее, что это условие действительно является постоянным (иначе оно даже не скомпилируется).Это также заставит вычислять выражение как константу ( незначительный вариант приводит к тому, что gcc испускает ветку в -O0
, а не в -O1
), что с предстоящим добавлением is_constant_evaluated()
может стать более важным в долгосрочной перспективе (возможно, даже отрицая мой первый абзац).
Единственное преимущество, которое я вижу, это явное указание программисту, что это if во время компиляции;однако, я бы сказал, что условное выражение самоочевидно.
Если обратиться к этому вопросу конкретно, то да, std::is_same<X, Y>::value
"самоочевидно", что оно является константным выражением ... потому что мыбыть знакомым с std::is_same
.Но менее очевидно, является ли foo<X>::value
константным выражением или foo<X>() + bar<Y>()
является константным выражением или чем-то более сложным, чем это.
Он видит if constexpr
, что делает тот факт, что он сам во время компиляции-объяснительная, а не содержание самого условия.