Специализация частичной шаблоны с несколькими параметрами шаблона

StackOverflow https://stackoverflow.com/questions/4706677

Вопрос

Продолжение Мое путешествие в мир вариационных шаблонов, Я столкнулся с другой проблемой.

Предполагая следующий класс шаблонов:

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 ). Анкет Я делаю что-то неправильно? Или я пытаюсь сделать что -то, что невозможно? Если так, есть ли веская причина, почему это невозможно?

Это было полезно?

Решение

Вероятно, этот ответ не будет очищать ваш вопрос напрямую, но следующий код, составленный на iDeone (GCC-4.5.1), когда я тестировал.

#include <cstdio>
#include <tuple>

template< class, class > struct S {
  S() { puts("primary"); }
};

template<
  template< class... > class T, class...TArgs
, template< class... > class U, class...UArgs
>
struct S< T< TArgs... >, U< UArgs... > > {
  S() { puts("specialized"); }
};

int main()
{
  S< int, int >  p;                                       // "primary"
  S< std::tuple< int, char >, std::tuple< float > >  s;   // "specialised"
}

Я не уверен, что этот код строго соответствует, но, насколько я прочитал N3225 14.5.3, я не смог найти утверждение, в котором упоминается, что пакет параметров шаблона должен быть последним параметром шаблона.

Редактировать:
Я перечитал N3225 и нашел следующие утверждения:

8.3.5/4 Если параметром по декларации заканчивается эллипсисом или пакетом параметров функции (14.5.3), количество аргументов должно быть равно или больше, чем количество параметров, которые не имеют аргумента по умолчанию и аргумента не являются функциональными параметрами.

14.8.2.5/10. -end Примечание

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top