c++11可变参数模板实现std::string fromat的功能

什么是可变参数模板?
相信你用过普通的模板函数,也就是这样。

template<typename T>
void func()
{
	...
}

可变参数模板的写法就是在这个基础上稍加改进,在参数前边加上三个点。这里说明一下可变参数模板如何取出参数的值,因为参数是可变的,所以,可以写成这个样子—— 一个头部分,和一个可变参数部分。函数实现的时候使用递归的方式将值一一取出。
所以模板的声明大致是这样。

template<typename THead,typename ...T>
void func()
{
	...
}

下面写点东西实践一下。

template <typename Harg,typename... Args>
void mySplicing(char *buf,Harg arg,Args ... args)
{
    //todo 将输入的参数拼接在一起,放到 buf中
    memcpy(buf,arg,strlen(arg));
    buf += strlen(arg);
    mySplicing(buf,args...);
}

按照上面的声明我门就得到了一个可以拼接多个任意字符的函数。事情真的解决了吗?仔细思考就会发现问题了,如果可变参数部分只有一个值,那么我们的函数并没有对应的实现。另外我们肯定也希望函数会在可变参数只有一个时停止递归。所以要实现这样的一个函数。

template <typename Harg>
void mySplicing(char *buf,Harg arg)
{
    memcpy(buf,arg,strlen(arg));
    buf += strlen(arg);
    return;
}

运行一下

int main ()
{
    char *buf = new char[128];
    mySplicing(buf,"a","b","c","d");
    std::cout<<buf<<std::endl; //输出 abcd
}

有了以上的经验接下来就可以尝试实现类似CString中的format()功能了。虽然c++中依然可以用sfprintf()实现功能。但是谁能拒绝造无意义的轮子呢?尤其时在摸鱼时间内……

void myFormat(std::string &target,const char * content)
{
    std::string add(content);
    target.append(add);
    return ;
}
template<typename Thead,typename... Types>
void myFormat(std::string &target,const char *content,Thead arg ,Types ... args)
{
    while(*content)
    {
        char a ,b;
        if(a = *content  == '%'  &&  (b = *++content )!= '%')
        {
            if(b == 'd')
            {
                int x;
                memcpy(&x,&arg,sizeof(int));    
                target.append(std::to_string(x));
                // std::cout<<"添加一个整数"<<x<<std::endl;
            }
            else if(b == 's')
            {
                int len = strlen((const char *)arg);
                char * buf = new char [len+ 1];
                memset(buf, 0, len);
                memcpy(buf,(const char *)arg,len);
                target.append(buf);
                delete []buf;
                buf = nullptr;
                // std::cout<<"添加一个字符"<<arg<<std::endl;
            }
            myFormat(target,++content,args...);
            return;
        }
        else
        {
            char add ;
            memcpy(&add,content++,sizeof(char));
            target.push_back(add);
            // std::cout<<"添加一个字符"<<add<<std::endl;
        }
            
    }
}
int main ()
{
    std::string str;
    myFormat(str,"[%s][%d],[%d],[%d],[%d]","fromat",1,2,3,4);
    std::cout<<str<<std::endl;//[fromat][1],[2],[3],[4]
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值