Esta não é a primeira vez que me deparo com uma situação em que há um ciclo dentro do código que depende de circunstâncias externas.
Por exemplo:
bool is_sqrt;
std::cin >> is_sqrt;
for(auto &i : vector)
{
do_smth_1(i);
//...
do_smth_n(i);
if(is_sqrt)
std::cout << std::sqrt(i);
else
std::cout << i * i;
do_smth(i);
}
Torna-se óbvio que você pode simplesmente mover a condição para fora do loop simplesmente escrevendo uma alternativa para ela em else
:
if(is_sqrt) for(auto &i : vector)
{
do_smth_1(i);
//...
do_smth_n(i);
std::cout << std::sqrt(i);
do_smth(i);
}
else for(auto &i : vector)
{
do_smth_1(i);
//...
do_smth_n(i);
std::cout << i * i;
do_smth(i);
}
Depois de algum tempo, o código cresce e os erros começam a aparecer por causa da necessidade de duplicar o código (e o fato da duplicação em si não é muito menos confuso). Eu vi o uso de std::function
/ *function
como uma solução, mas obviamente ambos os métodos são piores do que a duplicação de código em termos de desempenho. Na realidade, eu realmente não preciso dessa diferença de velocidade, a questão é apenas de interesse.
Se não há solução para essa situação em C++, talvez alguém tenha visto em outras linguagens? Seria muito interessante ver.
Com o modelo, você pode fazer
ou
Você pode criar um ponteiro de função que aponta para a função que você deseja chamar:
Observação:
std::sqrt
não é uma função endereçável , portanto, precisa ser encapsulada por uma função que seja.Você pode evitar
std::function
e usar lambdas diretamente, que a maioria dos compiladores otimiza hoje em dia, então não deve haver diferença no final para a versão totalmente duplicada do código:O código precisa
<type_traits>
ser incluído, e C++17 paraif constexpr
.Você pode generalizar isso além de verdadeiro/falso via
std::integral_constant
, mas precisa despachar explicitamente todos os valores possíveis que ele poderia ter. (Não escala bem se você tiver mais do que um punhado de valores possíveis que deseja despachar.)Diretrizes básicas do C++ Per.1: Não otimize sem motivo
Motivo:
Quanto a mim, usarei
Acho que isso pode ser um pouco mais rápido e não introduz muita complexidade .