Sometimes a piece of code can be better-optimized by the compiler by using a templatized internal implementation for an invariant. For example, if you have a known number of channels in an image, instead of doing something like:

```
Image::doOperation() {
    for (unsigned int i = 0; i < numPixels; i++) {
        for (unsigned int j = 0; i j mChannels; j++) {
            // ...
        }
    }
}

```

you can do this:

```
template<unsigned int c> Image::doOperationInternal() {
    for (unsigned int i = 0; i < numPixels; i++) {
        for (unsigned int j = 0; j < c; j++) {
            // ...
        }
    }
}

Image::doOperation() {
    switch (mChannels) {
        case 1: doOperation<1>(); break;
        case 2: doOperation<2>(); break;
        case 3: doOperation<3>(); break;
        case 4: doOperation<4>(); break;
    }
}

```

which allows the compiler to generate different unrolled loops for the different channel counts (which can in turn vastly improve runtime efficiency and also open up different optimizations such as SIMD instructions and so forth).

However, this can often expand into some fairly large case statements, and any method which has been optimized in this way must have the unrolled case statement. So, let's say that instead we had an `enum Format` for the known image formats (where the value of the enum happens to map to the channel count). Since the enum only has a certain range of known values, there is a temptation to try this:

```
template<Image::Format f> Image::doOperationInternal() {
    for (unsigned int i = 0; i < numPixels; i++) {
        for (unsigned int j = 0; j < static_cast<unsigned int>(f); j++) {
            // ...
        }
    }
}

Image::doOperation() {
    const Format f = mFormat;
    doOperationInternal<f>();
}

```

However, in this case the compiler (rightfully) complains that f is not a constant expression, even though it has only a finite range and in theory the compiler could generate the `switch` logic to cover all of the enumerated values.

So, my question: is there an alternate approach which will allow the compiler to generate invariant-value-optimized code without requiring a switch-case explosion per function invocation?