继续我的可变参数模板世界之旅,我遇到了另一个问题。
假设以下模板类:
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 )
。难道我做错了什么?还是我试图做一些不可能的事情?如果是这样,是否有充分的理由说明这是不可能的?