Предположим, у меня есть эта функция:
template<typename Side>
int GetSide(std::pair<int, int> i)
{
if (Side::mIsLeft)
return i.first;
else
return i.second;
}
Я вижу, что если mIsLeft
равно const
(даже не constexpr
), компилятор (gcc / clang) не будет генерировать какую-либо ветку:
int GetSide<LeftSide>(std::pair<int, int>):
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-16], rdi
mov eax, DWORD PTR [rbp-16]
pop rbp
ret
В отличие от того, когда mIsLeft
был НЕ const
, какая ветвь будет сгенерирована (как и ожидалось).
Теперь мой вопрос: это поведение (не генерирующее ветку) обеспечивается стандартом или гарантировано в любом случае? Или это просто компилятор видит возможность и использует ее? (это генерируется даже в -O0
)
Что если mIsLeft
будет constexpr
, это что-нибудь изменит?
Вы можете проверить код здесь, на кресте .
Почему меня это волнует?
Прежде чем найти это, в такой ситуации я бы использовал enable_if
и имел две разные специализации шаблона, чтобы избежать ненужной ветви, но это может упростить много кода.