将C++模板类的参数包隐藏到std::tuple
Modern C++引入了可变模板以及模板参数包,如下。
template<typename... Args>
class MultiArgs{};
可以使用std::tuple将参数包隐藏起来,如下。
template<typename... Args>
class MultiArgs{
using Tuple = std::tuple<Args...>;
};
那么,怎么取出某个参数类型呢?比如,第0个,以及最后一个参数。
可以借助std::tuple_element来实现。代码如下。
template<typename... Args>
class MultiArgs{
using Tuple = std::tuple<Args...>;
template<std::size_t N>
using Type = typename std::tuple_element<N,Tuple>::type;
};
同时,我们可以利用sizeof...来获取参数包的个数。
static constexpr auto Size = sizeof...(Args);
因此,如果需要取出第0个和最后一个参数,可以使用以下代码。
template<typename... Args>
class MultiArgs{
using Tuple = std::tuple<Args...>;
static constexpr auto Size = sizeof...(Args);
template<std::size_t N>
using Type = typename std::tuple_element<N,Tuple>::type;
using FirstArg = Type<0>;
using LastArg = Type<Size-1>;
};
如果上面的例子只能取出第0个和最后有一个参数,那么如果用户想要取出某个参数呢?完整代码如下。
#include <iostream>
#include <tuple>
#include <string>
template<typename... Args>
class MultiArgs{
public:
using Tuple = std::tuple<Args...>;
static constexpr auto Size = sizeof...(Args);
template<std::size_t N>
using Type = typename std::tuple_element<N,Tuple>::type;
using FirstArg = Type<0>;
using LastArg = Type<Size-1>;
MultiArgs(){}
~MultiArgs(){}
void PrintFirstArgType(){
std::cout<<"The first arg type:"<<typeid(FirstArg).name()<<std::endl;
}
void PrintLastArgType(){
std::cout<<"The last arg type:"<<typeid(LastArg).name()<<std::endl;
}
template<std::size_t N>
void PrintType(){
std::cout<<"The arg at index:"<<N<<" type:"<<typeid(Type<N>).name()<<std::endl;
}
};
int main(){
MultiArgs<int,double,float,std::string>::Type<3> my_string;
my_string = "hello world";
std::cout<<"my_string:"<<my_string<<std::endl;
MultiArgs<int,double,float,std::string> multi_args;
multi_args.PrintFirstArgType();
multi_args.PrintType<1>();
multi_args.PrintType<2>();
multi_args.PrintLastArgType();
return 0;
}