Non vengono fornite sufficienti informazioni.
La prima versione presuppone che b sia invariante rispetto a foo () e bar () per tutti i parametri a. La seconda versione presuppone che b non sia necessariamente così invariato e programmi difensivamente.
Probabilmente il compilatore non ha modo di sapere che b è in realtà invariante rispetto a foo () e bar (), e quindi non può tradurre la seconda versione nella prima. L'architettura hardware può o non può permettere che il suggerimento di David Arno sia fatto facilmente.
Se b non è invariante su foo () e bar (), la prima versione è errata. Se b è così invariato, la seconda versione può sprecare una discreta quantità di tempo testando
auto c = b; // assume invariance and force the compiler to believe it.
for (auto a : as) {
if (c) {
foo(a);
} else {
bar(a);
}
}
Quanto sopra assume l'invarianza di b e dice al compilatore di assumerlo ai fini dell'ottimizzazione. Ovviamente, se b non è invariante, è altrettanto negativo della prima versione originale, a un costo di maggiore complessità.