#c #templates #constants #c 14 #compile-time-constant
#c #шаблоны #константы #c 14 #постоянная времени компиляции
Вопрос:
Это функция, которую я пытаюсь упростить:
void BaseCharacter::ClimbLadder(float AxisValue)
{
if (AxisValue > 0.f)
ClimbUpLadder<bIsClimbingLaddersFast>();
else if (AxisValue < 0.f)
ClimbDownLadder<bIsClimbingLaddersFast>();
}
При этом bIsClimbingLaddersFast является логической переменной-членом. Теперь код не компилируется, потому что значение логического значения должно быть известно во время компиляции. Это тривиальное решение:
void BaseCharacter::ClimbLadder(float AxisValue)
{
if (bIsClimbingLaddersFast)
{
if (AxisValue > 0.f)
ClimbUpLadder<true>();
else if (AxisValue < 0.f)
ClimbDownLadder<true>();
}
else
{
if (AxisValue > 0.f)
ClimbUpLadder<false>();
else if (AxisValue < 0.f)
ClimbDownLadder<false>();
}
}
Но мне интересно, есть ли более чистый способ написать это, без повторяющихся операторов if-else .
Используется C 14.
Комментарии:
1. Не могли бы вы передать логическое значение в функцию в качестве аргумента вместо шаблонного аргумента?
2. Лично я бы изменил
ClimbUpLadder
andClimbDownLadder
с шаблонов на использование параметра bool. Тогда вы могли бы просто иметьif (AxisValue > 0.f) ClimbUpLadder(bIsClimbingLaddersFast); else if (AxisValue < 0.f) ClimbDownLadder(bIsClimbingLaddersFast);
3. Это намеренно, для чего у вас нет действий
AxisValue == 0.0f
?4. Хорошо, полезно знать. Я подумал, что это может повлиять на ответы.
5. независимо от того, какой трюк вы применяете, вам нужно каким-то образом сопоставить значение времени выполнения со значением времени компиляции. Решение Nathans делает вызывающего абонента более чистым, в то время как ваше решение накладывает отображение на вызывающего абонента, выберите свой яд. Если вы никогда не знаете
bIsClimbingLaddersFast
этого во время компиляции, то почему это вообще параметр шаблона?
Ответ №1:
Возможное (полностью непроверенный код) решение.
template<bool climb>
void BaseCharacter::ClimbLadder(float AxisValue) {
if (AxisValue > 0.f)
ClimbUpLadder<climb>();
else if (AxisValue < 0.f)
ClimbDownLadder<climb>();
}
void BaseCharacter::ClimbLadder(float AxisValue) {
if (bIsClimbingLaddersFast)
ClimbLadder<true>(AxisValue);
else
ClimbLadder<false>(AxisValue);
}