Специализация шаблонов C++ по функциям
Я играю со специализацией шаблонов, и я нашел проблему, которую я не могу решить; это мой код:
template<int length, typename T>
void test(T* array)
{
...
test<length-1>(array);
}
template<typename T>
void test<0>(T* array)
{
return;
}
Итак, что я пытаюсь сделать, это передать длину того, что должно быть обработано в шаблоне.
проблема в том, что компиляция этого, ну выводит навсегда:
a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template
a.cpp: In function 'void test(T*) [with int length= -0x000000081, T = int]':
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x00000007f, T = int]'
a.cpp:77:9: [ skipping 151 instantiation contexts ]
a.cpp:77:9: instantiated from 'void test(T*) [with int length= 28, T = int]'
a.cpp:77:9: instantiated from 'void test(T*) [with int length= 29, T = int]'
...
a.cpp: In function 'void test(T*) [with int length= -0x000000082, T = int]':
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000081, T = int]'
a.cpp:77:9: instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'
последние две строки в значительной степени совпадают с первыми.
мне казалось бы, его не поймать специализацию, следовательно:
a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template
Я прав?
и если я прав, я предполагаю, что проблема в том, что частичная специализация шаблонов не разрешена для шаблонов функций, так что было бы решением, создав структуру и используя специализацию на этом?
4 ответов
частичная специализация шаблонов функций не допускается. Херб Саттер объясняет, почему в своей статье " Почему Бы Не Специализировать Шаблоны Функций?".
чтобы обойти это ограничение, вам нужно использовать шаблоны классов. Затем можно написать шаблон регулярной функции, который использует этот шаблон класса.
эта конкретная ошибка, которую вы получаете, потому что вы забыли второй параметр в своей специализации. Если ты это вместо этого:
template<int length, typename T>
void test(T* array)
{
//...
test<length-1,T>(array);
}
template<typename T>
void test<0,T>(T* array)
{
return;
}
GCC жалуется следующим образом:
ошибка: частичная специализация шаблона функции "test" не допускается
функции не могут быть частично специализированы. Чтобы обойти это, вызовите функцию шаблона в классе:
template<int length, typename T>
struct helper
{
static void go(T* array)
{
...
helper<length-1, T>::go(array);
}
};
template<typename T>
struct helper<0, T>
{
static void go(T* array)
{
...
}
};
template<int length, typename T>
void test(T* array)
{
...
helper<length, T>::go(array);
}
частичная специализация шаблонов функций не допускается.
чтобы обойти это, вы можете сделать test
статический член шаблона класса, и частично специализировать класс.
вы можете обойти с помощью вспомогательного класса. Для целей illustrational:
template<typename T, typename U> struct helper_t {
static int foo () { return 0; }
};
template<typename T> struct helper_t<T,T> {
static int foo () { return 1; }
};
template <typename T, typename U>
int frob () {
return helper_t<T,U>::foo();
}