简体   繁体   English

具有多个模板参数包的部分模板专业化

[英]Partial template specialization with multiple template parameter packs

Continuing my journey into the world of variadic templates , I encountered another problem. 继续我的可变模板世界之旅 ,我遇到了另一个问题。

Assuming the following template class: 假设以下模板类:

template < typename T >
struct foo 
{
    //default implementation
};

it is possible to partially specialize it for variadic template instantiations like this: 它可以部分地专门用于变量模板实例化,如下所示:

template < template < typename ... > class T, typename ...Args >
struct foo< T< Args... > >
{
    //specialized implementation
};

With this, foo< int > will correspond to the default implementation and foo< std::tuple< int, char > > to the specialized implementation. 有了这个, foo< int >将对应于默认实现, foo< std::tuple< int, char > >将对应于专用实现。

However, things become more complicated when using several template parameters. 但是,使用多个模板参数时,事情会变得更加复杂。 For example, if we have the following template class 例如,如果我们有以下模板类

template < typename T, typename U >
struct bar {};

and we want to partially specialize it as we did for foo , we cannot do 我们想要像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;

Indeed, if I am correct, we can only have one template parameter pack and it must be positioned at the end of the parameter list. 实际上,如果我是正确的,我们只能有一个模板参数包,它必须位于参数列表的末尾。 I understand why this is mandatory in template declarations, but for certain partial template specialization (like the example above), this should not be an issue. 我理解为什么这在模板声明中是强制性的,但对于某些部分模板特化(如上面的例子),这应该不是问题。

Is it possible to achieve partial template specialization with multiple template parameter packs? 是否可以使用多个模板参数包实现部分模板专业化?


Edit : Now I feel silly...the code I gave above compiles perfectly (at least with gcc 4.5). 编辑 :现在我觉得很傻......我上面给出的代码完美编译(至少使用gcc 4.5)。 The compile error I had was not because of multiple parameter packs, but because of their use as member functions parameters. 我遇到的编译错误不是因为多个参数包,而是因为它们被用作成员函数参数。 In the partial specialization of bar , I tried to define a member function that takes both TArgs and UArgs parameters: bar的部分特化中,我尝试定义一个同时TArgsUArgs参数的成员函数:

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

On the member function declaration, gcc gives me the error 在成员函数声明中,gcc给出了错误

parameters packs must be at the end of the parameter list. 参数包必须位于参数列表的末尾。

As far as I can tell, the compiler should be able to define the correct member function for a given template instantiation, eg bar< std::tuple< int, char >, std::tuple< float > > should contain a member function void method( int, char, float ) . 据我所知,编译器应该能够为给定的模板实例化定义正确的成员函数,例如bar< std::tuple< int, char >, std::tuple< float > >应该包含成员函数void method( int, char, float ) Am I doing something wrong? 难道我做错了什么? Or am I trying to do something that is not possible? 还是我想做一些不可能的事情? If so, is there a good reason why this is not possible? 如果是这样,是否有充分理由说明这是不可能的?

Probably this answer won't clear your question directly, but the following code compiled on ideone(gcc-4.5.1) when I tested. 可能这个答案不会直接解决你的问题,但是当我测试时,下面的代码在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"
}

I'm not sure this code is strictly conformant, but as far as I read N3225 14.5.3, I couldn't find the statement which mentions that template parameter pack has to be the last template parameter. 我不确定这段代码是否严格符合,但就我读N3225 14.5.3而言,我找不到提及模板参数包必须是最后一个模板参数的语句。

Edit: 编辑:
I reread N3225 and found the following statements: 我重读了N3225并发现了以下声明:

8.3.5/4 If the parameter-declaration-clause terminates with an ellipsis or a function parameter pack (14.5.3), the number of arguments shall be equal to or greater than the number of parameters that do not have a default argument and are not function parameter packs. 8.3.5 / 4如果参数声明子句以省略号或函数参数包(14.5.3)结束,则参数个数应等于或大于没有默认参数的参数个数。不是函数参数包。

14.8.2.5/10 [Note: A function parameter pack can only occur at the end of a parameter-declarationlist(8.3.5). 14.8.2.5/10 [注意:函数参数包只能出现在参数声明列表(8.3.5)的末尾。 -end note] - 尾注]

So, as you mentioned, function parameter pack has to be the last parameter unfortunately. 因此,正如您所提到的,不幸的是,函数参数包必须是最后一个参数。
A non-template member function of a class template is an ordinary function for that class when it is instantiated(fully specialized). 类模板的非模板成员函数是实例化(完全专用)时该类的普通函数。 So I wish that the code in this question can be compiled logically, as a special case. 所以我希望这个问题中的代码可以逻辑编译,作为一个特例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM