Metaprogramowanie - silnia, konkretyzacja.

Metaprogramowanie - silnia, konkretyzacja.
0

mam sobie szablon funkcji:

Kopiuj
template<unsigned n>
long long unsigned silnia()
{
	return silnia<n-1>()*n;
}

template<>
long long unsigned silnia<0>()
{
	return 1 ;
}

//gdzieś tam w kodzie:
std::cout<<silnia<5>()<<"\n";

myślałem, że skoro jest to metaprogramowanie, kompilator skonkretyzuje mi to wywołanie po prostu do:

Kopiuj
return 120 ;

jednak nie:

Kopiuj
 
_Z6silniaILj5EEyv:
.LFB961:
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	pushl	%ebx
	subl	$4, %esp
	.cfi_offset 3, -12
	**call	_Z6silniaILj4EEyv**
	imull	$5, %edx, %ecx
	imull	$0, %eax, %ebx
	addl	%ebx, %ecx
	movl	$5, %ebx
	mull	%ebx
	addl	%edx, %ecx
	movl	%ecx, %edx
	addl	$4, %esp
	popl	%ebx
	popl	%ebp
	ret
	.cfi_endproc


(...)


_Z6silniaILj4EEyv:
.LFB965:
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	subl	$8, %esp
	**call	_Z6silniaILj3EEyv**
	shldl	$2, %eax, %edx
	sall	$2, %eax
	leave
	ret
	.cfi_endproc


(...)


_Z6silniaILj3EEyv:
.LFB968:
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	pushl	%ebx
	subl	$4, %esp
	.cfi_offset 3, -12
	**call	_Z6silniaILj2EEyv**
	imull	$3, %edx, %ecx
	imull	$0, %eax, %ebx
	addl	%ebx, %ecx
	movl	$3, %ebx
	mull	%ebx
	addl	%edx, %ecx
	movl	%ecx, %edx
	addl	$4, %esp
	popl	%ebx
	popl	%ebp
	ret
	.cfi_endproc

(...)


_Z6silniaILj2EEyv:
.LFB971:
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	subl	$8, %esp
	**call	_Z6silniaILj1EEyv**
	shldl	$1, %eax, %edx
	addl	%eax, %eax
	leave
	ret
	.cfi_endproc


(...)


_Z6silniaILj1EEyv:
.LFB973:
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	**call	_Z6silniaILj0EEyv**
	popl	%ebp
	ret
	.cfi_endproc


(...)


_Z6silniaILj0EEyv:
.LFB958:
	.cfi_startproc
	.cfi_personality 0x0,__gxx_personality_v0
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	**movl	$1, %eax**  # WRESZCIE
	movl	$0, %edx
	popl	%ebp
	ret
	.cfi_endproc

czemu tak jest? jaki w takim razie jest sens metaprogramowania z użyciem szablonów funkcji, skoro w miejscu wywołania silnia<200>() tak naprawdę tworzy się 200 funkcji wywołujących siebie nawzajem?

RE
A z optymalizacjami włączonymi kompilujesz?
ZJ
Zrobiłem test z printfem oraz -O3 i wyszło movl $120, 4(%esp).
Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około 2 godziny
0

Ale tym kodem przecież generujesz n funkcji. Zobacz na Wikipedię: http://en.wikipedia.org/wiki/Template_metaprogramming tam jest używany enum, czyli zbiór statycznych stałych, a więc obliczanych z definicji w czasie kompilacji.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
AT
  • Rejestracja:ponad 13 lat
  • Ostatnio:ponad 13 lat
  • Postów:22
1

A weź sprawdź to:

Kopiuj
 template < int N >
struct silnia {
    static int const value = N*silnia<N-1>::value;
};

template < >
struct silnia<0> {
    static int const value = 1;
};

To podejście jest zazwyczaj stosowane ;)

edytowany 1x, ostatnio: Atael
0

Metaprogramowanie to nie tylko wyliczanie wartości w czasie kompilacji (tojest raczej nie często spotykane zastosowanie) polecam poczytać o boost mpl lub http://dabprograming.blogspot.com/2012/12/metaprogramowanie-cz2-polimorfizm.html

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.