P
Einfach mal den erzeugten Assemblercode ansehen. Hier ist die nicht-template Version:
int k = 0;
void do_n_times(unsigned n)
{
for(unsigned i = 0; i < n; ++i)
{
k += i;
}
}
int main()
{
do_n_times(5);
}
ergibt
do_n_times(unsigned int):
xor eax, eax
test edi, edi
mov edx, DWORD PTR k[rip]
je .L1
.L5:
add edx, eax
add eax, 1
cmp edi, eax
jne .L5
mov DWORD PTR k[rip], edx
.L1:
rep ret
main:
add DWORD PTR k[rip], 10
xor eax, eax
ret
k:
.zero 4
Es wird zwar Code für die Funktion generiert, allerdings ist das Ergebnis schon vorberechnet in der main-Funktion und wird einfach nur noch in die Variable geschrieben.
Man kann die Funktion static machen oder in einen anonymen Namespace packen, dann wird auch kein Code mehr dafür generiert.
Die Template-Version
int k = 0;
template<unsigned int n>
void t_do_n_times()
{
for(unsigned i = 0; i < n; ++i)
{
k+= i;
}
}
int main()
{
t_do_n_times<5>();
}
ergibt
main:
add DWORD PTR k[rip], 10
xor eax, eax
ret
k:
.zero 4
Hier ist das gleiche Ergebnis, wie mit static oder namespace {}.
Fazit: Nein, hat keinen Vorteil, wenn dann kommt es auf den Inhalt von do_it an, ob der Compiler das zur Compilezeit berechnen kann.