具有多个模板参数包的部分模板专门化 [英] Partial template specialization with multiple template parameter packs

查看:108
本文介绍了具有多个模板参数包的部分模板专门化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

继续我踏上可变模板世界,我遇到了另一个问题。

Continuing my journey into the world of variadic templates, I encountered another problem.

假设下面的模板类:

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

有了这个, foo< int> 将对应于默认实现,并且 foo< std :: tuple< int,char> >

With this, foo< int > will correspond to the default implementation and foo< std::tuple< int, char > > to the specialized implementation.

但是,使用多个模板参数时,事情变得更复杂。例如,如果我们有以下模板类

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

,我们想要部分专门化,因为 foo ,我们不能做

and we want to partially specialize it as we did for foo, we cannot do

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?

编辑 。我给出的代码完全编译(至少用gcc 4.5编译)。编译错误我不是因为多个参数包,而是因为它们用作成员函数参数。在 bar 的部分专门化中,我尝试定义一个成员函数,它接受 TArgs UArgs 参数:

Edit: Now I feel silly...the code I gave above compiles perfectly (at least with 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:

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给出错误

On the member function declaration, gcc gives me the error


参数包必须在参数列表的结尾。

parameters packs must be at the end of the parameter list.

我可以告诉,编译器应该能够为给定的模板实例化定义正确的成员函数,例如 bar < std :: tuple< int,char>,std :: tuple< float> > 应包含成员函数 void方法(int,char,float)。我做错了什么?还是我想做一些不可能的事情?

As far as I can tell, the compiler should be able to define the correct member function for a given template instantiation, e.g. bar< std::tuple< int, char >, std::tuple< float > > should contain a member function 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?

推荐答案

这个答案可能不会直接清除你的问题,
,但下面的代码在我测试时在ideone(gcc-4.5.1)上编译。

Probably this answer won't clear your question directly, but the following code compiled on ideone(gcc-4.5.1) when I tested.

#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,我找不到那个提到
的语句,模板参数包必须是最后一个模板参数。

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,发现了以下语句:


I reread N3225 and found the following statements:


8.3.5 / 4如果parameter-declaration-clause
以省略号或
函数参数pack(14.5.3)结束,则
参数个数应等于
或大于
参数的数量,没有默认的
参数,并且不是函数
参数包。

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.

14.8.2.5/10 [注意:函数参数包只能出现在
参数声明列表(8.3.5)的
结尾。 -end
note]

14.8.2.5/10 [Note: A function parameter pack can only occur at the end of a parameter-declarationlist(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.

这篇关于具有多个模板参数包的部分模板专门化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆