如何在使用可变参数模板和多个参数包的部分模板专用中使用默认模板参数

时间:2014-10-14 17:56:49

标签: c++ templates specialization variadic default-parameters

我对使用两种不同的可变参数包的模板类的特化有问题。详细说明,我们有一个像“变量类型”的

template< typename... Arguments > 
struct VariadicType{};

使用单一类型和两个不同的可变参数包的模板类是

template< typename Type , class , class > 
struct foo{};

我们专门使用此模板来获取对两个不同参数包的访问权限,如下所示:

template<  typename Type ,
           template< class... > class FirstPack_Container  , class... First  ,
           template< class... > class SecondPack_Container , class... Second      >
struct foo< Type , FirstPack_Container< First... > , SecondPack_Container< Second... > > {
     //
     foo(First... first , Second... second){
          std::cout << "sizeof...(first)  = " << sizeof...(first)  << std::endl;
          std::cout << "sizeof...(second) = " << sizeof...(second) << std::endl;
     }
};

对于foo类型对象的实例化,我们必须输入两个不同的VariadicType:

typedef VariadicType<int,float,double> FirstPack;
typedef VariadicType<double,std::string> SecondPack;

掌握这些类型我们可以写

foo<int,FirstPack,SecondPack> my_foo_object(1,2.,3.,4.,"bla");

但是如果你想只使用一个可变参数包的foo结构,我们必须写:

typedef VariadicType<> EmptyType;
foo<int,FirstPack,EmptyType> my_bar_object(1,2.,3.);

因此,问题出现了,如果有可能或工作流程为专用的foo结构提供一个EmptyType作为SecondPack_Container的默认模板参数。或者,是否可以仅为一个可变参数包专门化foo,如果是,如何?

为了简单起见,这里有一个完全工作的最小cpp-File用于编译(使用gcc 4.7):

#include<string>
#include<iostream>

// Compile with Debug-Information : g++ -o X.bin -Wall -Wextra -pedantic -std=c++11 -g X.cpp
// Holder-Class for variadic Arguments
template< typename... Arguments >
struct VariadicType{};

// Template Class for usage of two different variadic Parameter-Packs
template< typename Type , class , class > 
struct foo{};

// Specialization of foo for direct Access of the two different variadic Parameter-Packs
template<      typename Type ,
               template< class... > class FirstPack_Container  , class... First  ,
               template< class... > class SecondPack_Container , class... Second      >
struct foo< Type , FirstPack_Container< First... > , SecondPack_Container< Second... > > {
     //
     foo(First... first , Second... second){
         std::cout << "sizeof...(first)  = " << sizeof...(first)  << std::endl;
         std::cout << "sizeof...(second) = " << sizeof...(second) << std::endl;
     }
};

int main(){
     // Definition of "variadic Pack Types" for usage in foo:
     typedef VariadicType<int,float,double> FirstPack;
     typedef VariadicType<double,std::string> SecondPack;
     //
     // Instantiation of foo-Object with two Parameter-Packs:
     foo<int,FirstPack,SecondPack> my_foo_object(1,2.,3.,4.,"bla");
     //
     // But now: the second parameter Pack has to be empty.
     // A "variadic empty Type":
     typedef VariadicType<> EmptyType;
     // Instantiation of a foo-Object with only FirstPack:
     foo<int,FirstPack,EmptyType> my_bar_object(1,2.,3.);

     return 0;
}

修改

抱歉,我的问题不是很简洁!仅对一个可变参数包进行struct foo的特化是显而易见的。我想避免将整个结构再植入专业化的时间。所以我做了以下简单的技巧:我创建了一个可变的TemplateTypeFactory,如下所示:

typedef VariadicType<> EmptyType;

template<typename Type,class X1,class X2=EmptyType>
struct TemplateTypeFactory{};

template<  typename ReturnType,
           template<class...> class FirstType  , class... first  ,
           template<class...> class SecondType , class... second >
struct TemplateTypeFactory<ReturnType,FirstType<first...>,SecondType<second...>>{
      typedef foo<ReturnType,VariadicType<first...>,VariadicType<second...>> Type;
};

template<  typename ReturnType,
           template<class...> class FirstType  , class... first     >
struct TemplateTypeFactory<ReturnType,FirstType<first...>,Empty_Type>{
      typedef foo<ReturnType,VariadicType<first...>,Empty_Type> Type;
};

注意:在TemplateFactory的Deklaration中,我使用EmptType作为第二个模板类型X2的默认参数。

要使用此TemplateType Factory,我们可以写:

typedef TemplateTypeFactory<int,FirstPack,SecondPack> foo_type_3;
foo_type_2::Type foo_3(1,2.,3.,4.,"bla");

typedef TemplateTypeFactory<int,FirstPack> foo_type_4;
foo_type_4::Type foo_4(1,2.,3.);

因此问题由我自己解答!

0 个答案:

没有答案