специализация шаблона функции c ++ для массива с определенным размером - PullRequest
8 голосов
/ 03 февраля 2012

Пожалуйста, обратите внимание на следующий код:

#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;
}

Если я скомпилирую и запуском, я вижу это:

> 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

Ясно, что sizeof, напечатанный внутри func, относитсяразмер указателя, а не размер массива typedef, как указано в main().

Теперь мне интересно, как правильно сделать трюк для того, чтобы мой func специализировался на такомтак, что он правильно знает о моем typedef и его размере.

Кто-нибудь здесь может мне помочь, пожалуйста?

Действительно спасибо.


РЕДАКТИРОВАТЬ

Реализация специализации:

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;
}

Вывод:

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

Я заметил изменение типа с Pc на A16_c.Это помогает?

Ответы [ 2 ]

13 голосов
/ 03 февраля 2012

Если вы хотите специализировать свою функцию для массивов, сделайте следующее:

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;
}
2 голосов
/ 03 февраля 2012

При использовании в качестве выражений rvalue массивы распадаются на указатели на первый элемент.Функция, которую вы определили, принимает указатель и выполняет то, что ожидается.Если вы хотите сохранить массив как массив, вам нужно передать его по ссылке, и, поскольку количество элементов является частью типа, вы, вероятно, захотите использовать его как другой аргумент шаблона:

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