Sto sperimentando nuove funzionalità del C++ 11, soprattutto in constexpr. Se voglio codificare un pow con il modello mi limiterò a fare:constexpr versus template, pow function
//pow
template<class T, std::size_t n>
struct helper_pow{
inline static T pow(T const& a){
return a*helper_pow<T,n-1>::pow(a);
}
};
//final specialization pow
template<class T>
struct helper_pow<T,0>{
inline static T pow(T const& a){
return 1;
}
};
Ora, se io chiamo la mia funzione nel mio codice semplicemente:
pow<double,5>(a) // where a is double
il gruppo corrispondente verrà (gcc 4.8. 0, -O2):
movapd %xmm0, %xmm1
movsd %xmm0, 24(%rsp)
mulsd %xmm0, %xmm1
movq %rbx, %rdi
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
Fine il codice è in linea.
Se so che sto cercando la versione constexpr, ho
template <class T>
inline constexpr T pow(T const& x, std::size_t n){
return n>0 ? x*pow(x,n-1):1;
}
Il gruppo corrispondente è ora:
movsd 24(%rsp), %xmm2
leaq 24(%rsp), %rdi
movl $4, %esi
movsd %xmm2, 8(%rsp)
call __Z3powIdET_RS0_m
dove la funzione __Z # powIdET_RS0_m sembra definire con
LCFI1:
mulsd %xmm1, %xmm0
movapd %xmm0, %xmm2
mulsd %xmm1, %xmm2
mulsd %xmm2, %xmm1
movapd %xmm1, %xmm0
ret
Quindi hai qualche idea sul perché con constexpr la funzione non è in linea e considera come "un esterno " funzione ? Esiste un modo per forzare la linea di una funzione di constexpr? Il migliore.
Perché l'argomento per constexpr 'pow' non è const? –
Se interpreto correttamente lo smontaggio del mio g ++ 4.8.1 ('-O2'), * esegue * inline (e srotola la ricorsione di) il tuo' pow' per piccoli esponenti, se l'esponente è un letterale (noto alla compilazione -tempo dovrebbe essere sufficiente). Per gli esponenti più grandi (ad esempio 10), introduce una funzione. A '-O3', è in linea anche per i maggiori esponenti (14). – dyp
Sebastian: Dimentico^_ ^, DyP: interessante, proverò una nuova versione del compilatore –