C++2.0——语言新特性之Variadic Templates

variadic template 特性本身是一个很自然的需求,它完善了 C++ 的模板设计手段。原来的模板参数可以使类和函数的参数类型“任意化”,如果再加上“参数个数的任意化”,那么在参数方面的设计手段就基本上齐备了,有了variadic template 显然可以让设计出来的函数或是类有更大的复用性。因为有很多处理都是与“处理对象的个数”关系不大的,比如说打屏(printf),比如说比较大小(max,min),比如函数绑定子(bind,function要对应各种可能的函数就要能“任意”参数个数和类型)。如果不能对应任意个参数,那么就总会有人无法重用已有的实现,而不得不再重复地写一个自己需要的处理,而共通库的实现者为了尽可能地让自己写的类(函数)能复用在更多的场景,也不得不重复地写很多的代码或是用诡异的技巧,宏之类的去实现有限个“任意参数”的对应。

语法

void print() 
{
}

template <typename T,typename... Types>
void print(const T& firstArg,const Types&... args
{
    cout << firstArg << " sizeof(args) " << sizeof...(args) << endl;
    print(args...);
}

模板参数Types:在模板参数 Types 左边出现省略号 ... ,就是表示 Types 是一个模板参数包(template type parameter pack)

函数参数args:函数参数args的类型定义一个模板参数包,args是一个可变参数

函数实参args:args是一个可变参数,省略号...出现在其后

sizeof...(args):计算不定模板参数的个数

使用

1. 利用 variadic template 实现printf:

void printf(const char *s)
{
    while (*s) {
        if (*s == '%') {
            if (*(s + 1) == '%') {
                ++s;
            }
            else {
                throw std::runtime_error("invalid format string: missing arguments");
            }
        }
        std::cout << *s++;
    }
}
 
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
    while (*s) {
        if (*s == '%') {
            if (*(s + 1) == '%') {
                ++s;
            }
            else {
                std::cout << value;
                // call even when *s == 0 to detect extra arguments
                printf(s + 1, args...);
                return;
            }
        }
        std::cout << *s++;
    }
    throw std::logic_error("extra arguments provided to printf");
}

2. 利用递归继承和variadic template 实现 tuple:

template<typename... Elements> class tuple;
template<typename Head, typename... Tail>
class tuple<Head, Tail...> : private tuple<Tail...> {
    Head head;
public:
    /* implementation */
};
template<>
class tuple<> {
    /* zero-tuple implementation */
};

VS2015的测试信息:

	tuple<int, float, string> t(1,2.1,"test");

	cout << t._Myfirst._Val << endl;
	cout << t._Get_rest()._Myfirst._Val << endl;
	cout << t._Get_rest()._Get_rest()._Myfirst._Val << endl;

输出:

参考文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值