Продолжая моего путешествия в мир вариационных шаблонов , я столкнулся с другой проблемой.
Предполагая следующий класс шаблона:
template < typename T >
struct foo
{
//default implementation
};
можно частично специализировать его для создания экземпляров шаблонов с переменными параметрами, например:
template < template < typename ... > class T, typename ...Args >
struct foo< T< Args... > >
{
//specialized implementation
};
При этом foo< int >
будет соответствовать реализации по умолчанию, а foo< std::tuple< int, char > >
- специализированной реализации.
Однако все становится сложнее при использовании нескольких параметров шаблона. Например, если у нас есть следующий шаблон класса
template < typename T, typename U >
struct bar {};
и мы хотим частично специализировать его, как мы это делали для foo
, мы не можем сделать
template < template < typename ... > class T, typename ...TArgs,
template < typename ... > class U, typename ...UArgs >
struct bar< T< TArgs... >, U< UArgs... > > {};
//This would correspond to the specialized version with
//T=std::tuple,
//TArgs=int,char
//U=std::tuple,
//UArgs=float
bar< std::tuple< int, char >, std::tuple< float > > b;
Действительно, если я прав, у нас может быть только один пакет параметров шаблона, и он должен располагаться в конце списка параметров. Я понимаю, почему это является обязательным в объявлениях шаблонов, но для определенной частичной специализации шаблонов (как в примере выше) это не должно вызывать проблем.
Можно ли добиться частичной специализации шаблона с несколькими пакетами параметров шаблона?
Редактировать : Теперь я чувствую себя глупо ... код, который я дал выше, прекрасно компилируется (по крайней мере, с gcc 4.5). Ошибка компиляции была не из-за множества пакетов параметров, а из-за их использования в качестве параметров функций-членов. В частичной специализации bar
я попытался определить функцию-член, которая принимает параметры TArgs
и UArgs
:
template < template < typename ... > class T, typename ...TArgs,
template < typename ... > class U, typename ...UArgs >
struct bar< T< TArgs... >, U< UArgs... > >
{
void method( TArgs... targs, UArgs... uargs ) //compile error here
{
}
};
При объявлении функции-члена gcc выдает ошибку
пакеты параметров должны находиться в конце списка параметров.
Насколько я могу судить, компилятор должен иметь возможность определить правильную функцию-член для данного экземпляра шаблона, например, bar< std::tuple< int, char >, std::tuple< float > >
должен содержать функцию-член void method( int, char, float )
. Я делаю что-то неправильно? Или я пытаюсь сделать то, что невозможно? Если так, есть ли веская причина, почему это невозможно?