2

I'm a fairly new to C++ and the whole template programming, im sorry this question might be a bit dumb or does not make much sense, but I have the following code

enum SomeEnum : int {FIRST, SECOND, THIRD, FOURTH};

template<SomeEnum Val>
void Foo(){
... some code ...
   int x = 0;
   if(Val == FIRST){
      x = DoCalculationA();
   }
   else if(Val == THIRD){
      x = DoCalculationB();
   }
... some more code that uses 'x', and perhaps some more if checks on Val  ...
}

Can i assume that the compiler will optimize away the if statements - that when i call this function for example as Foo<FIRST>(), it wont do any if checks on the Val? Is this even an approriate way to use templates, or should i just be passing the enum as an argument? The code i have needs to run very fast, so any extra if branches are highly problematic.

Edit:

Just to make it a bit more clear. Foo is called like this

Bar(SomeOtherEnum someOtherEnum){
   switch(someOtherEnum){
      case VALUE_1:
         Foo<FIRST>();
      case VALUE_2:
         Foo<SECOND>();
      case VALUE_3:
         Foo<THIRD>();
      default:
         Foo<FOURTH>();
   }
}
Jane Doe
  • 480
  • 3
  • 15
  • You can replace `if..elseif` for `Val` with `switch..case` statements. https://stackoverflow.com/q/97987 – kiner_shah Jun 27 '21 at 11:07
  • Hey , are those `if` statements dead? – anirudh Jun 27 '21 at 11:07
  • No, this function will be called many times with all the different enum values. There are more if branches further in `foo` dependant on the value of `Val`. So what i basically want to do is have some `Bar` function call the appropriate `Foo` template depending on some enum variable in the `Bar` function. Essentially in `Bar` there will be a master switch statement calling the proper `Foo` template. – Jane Doe Jun 27 '21 at 11:36
  • 3
    Use `if constexpr`? – 2b-t Jun 27 '21 at 12:11
  • So if i use `if constexpr` on template values i can safely assume the branching will be gone? I think that might be what i was looking for, thanks! – Jane Doe Jun 27 '21 at 12:26
  • @JaneDoe Yeah, that is what is it for. So you can have other branches that actually would only compile with one type but not with another. – 2b-t Jun 27 '21 at 13:05

1 Answers1

2

The C++ standard allows the C++ compiler to perform any optimization that has no observable effects. However the C++ compiler is not obligated to do so.

In your specific case, there does not seem to be any observable effects of the described optimization, and it is a fairly simple optimization. Therefore it's likely that your C++ compiler will not generate the code that will never be used. However there is no formal requirement to do so, so in order to determine whether this is the case it will be necessary to examine the compiled code with a debugger.

Whether or not the C++ compiler performs this kind of an optimization also often depends on the compilation options, too. It is also possible to force the compiler's hand and force it to avoid compiling the unneeded code. The approach depends on the C++ version. C++17's simplest solution is if constexpr. Alternatives, that work with earlier C++ versions, usually involve some refactoring and template specializations.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148