2012-02-03 13 views
7

Proszę rozważyć następujący kod:C++ Specjalizacja szablonu funkcja znanej wielkości typedefed tablicy

#include <iostream> 
#include <typeinfo> 


template< typename Type > 
void func(Type var) 
{ 
    std::cout << __FUNCTION__ << ": var = " << var << " [" << typeid(var).name() << "]." << std::endl; 
    std::cout << "-> var is SCALAR. Size = " << sizeof(Type) << std::endl; 
} 

#if 1 
template< typename Type > 
void func(Type * var) 
{ 
    std::cout << __FUNCTION__ << ": var = " << var << " [" << typeid(var).name() << "]." << std::endl; 
    std::cout << "-> var is ARRAY. Size = " << sizeof(Type *) << std::endl; 
} 
#endif 

int main() 
{ 
    typedef char char16[ 16 ]; 

    char16 c16 = "16 bytes chars."; 

    std::cout << "Size of char16 = " << sizeof(char16) << std::endl; 

    func(c16); 

    return 0; 
} 

Gdybym go skompilować i uruchomić, widzę to:

> g++ -Wall -g3 spec_f_pointer.cpp -o spec_f_pointer 
> ./spec_f_pointer 
Size of char16 = 16 
func: var = 16 bytes chars. [Pc]. 
->  var is ARRAY. Size = 8 

Wyraźnie sizeof drukowane wewnątrz func odnosi do rozmiaru wskaźnika, a nie do rozmiaru tablicy typedef, podanej w main().

Teraz zastanawiam się, jak poprawnie zrobić sztuczkę, aby moja specjalizacja w func specjalizuje się w taki sposób, aby poprawnie znała mój typedef i jego rozmiar.

Czy ktoś tu może mi pomóc, proszę?

Naprawdę dzięki.


EDIT

Wdrożenie specjalizacji:

template< typename Type > 
void func(Type * const &var) 
{ 
    std::cout << __FUNCTION__ << ": var = " << var << " [" << typeid(var).name() << "]." << std::endl; 
    std::cout << "-> var is ARRAY. Size = " << sizeof(Type *) << std::endl; 
} 

Wyjście jest:

Size of char16 = 16 
func: var = 16 bytes chars. [A16_c]. 
->  var is SCALAR. Size = 16 

zauważyłem zmiany typu z Pc do A16_c. Czy to pomaga?

+0

Twoje podejście jest po prostu źle. Za pomocą wskaźnika przyjmuje się wskaźnik, który traci wszystkie informacje o rozmiarze tablicy. Dlaczego nie postępujesz zgodnie z radami mojego i @ Davida? –

Odpowiedz

12

Jeśli chcesz się specjalizować swoją funkcję tablic, to zrobić:

template<typename T, int N> 
void func(T(&var)[N]) 
{ 
    typedef T Type[N]; 
    std::cout << __FUNCTION__ << " [" << typeid(var).name() << "]." << std::endl; 
    std::cout << "-> var is ARRAY. Size = " << sizeof(Type) << std::endl; 
    std::cout << "Number of elements: " << N << std::endl; 
    std::cout << "Size of each element: " << sizeof(T) << std::endl; 
} 
+0

powinno to być size_t, a nie int? – David

+2

@Dave: Nie ma znaczenia, jeśli mnie zapytasz. –

+0

Nie ma ... dopóki nie masz tablicy, w której int_max David

1

Kiedy używany jako wyrażenia rvalue, tablice do rozkładu wskaźników do pierwszego elementu. Zdefiniowana funkcja przyjmuje wskaźnik i robi to, czego się oczekuje. Jeśli chcesz zachować tablicę jako tablicę, musisz przekazać ją przez odniesienie, a ponieważ liczba elementów jest częścią typu, który prawdopodobnie chcesz użyć jako kolejnego argumentu szablonu:

template <typename T, int N> 
void f(T(&arg)[N]) { 
    cout << sizeof arg << endl; 
}