转发参数包的例子

16.58 为你的StrVec类添加emplace_back函数。

StrVec.h(注意,函数模板和模板成员函数的定义和声明要放在一起,通常都放在头文件中)

#ifndef STRVEC_H
#define STRVEC_H
#include<iostream>
#include<string>
#include<utility>
#include<memory>
#include<initializer_list>
using namespace std;
class StrVec
{
friend bool operator==(const StrVec&,const StrVec&);
friend bool operator!=(const StrVec&,const StrVec&);
public:
    StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
    StrVec(const StrVec&);
    StrVec& operator=(const StrVec&);
    ~StrVec() noexcept;
    //重载
    void push_back(const string&);
    void push_back(string&&);
    // emplace member covered in chapter 16
    template <class... Args> void emplace_back(Args&&...);
    size_t size() const { return first_free-elements;}
    size_t capacity() const { return cap-elements;}
    string *begin() const  {cout<<"begin"<<endl; return elements;}
    string *end() const { cout<<"end"<<endl; return first_free;}

    void reserve(size_t n);
    void resize(size_t n,string s=string());

    StrVec(initializer_list<string> il)
    {
        auto newcapacity=il.size();
        auto newdata=alloc.allocate(newcapacity);
        auto dest=newdata;
        auto elem=il.begin();
        while(elem!=il.end())
            alloc.construct(dest++,*elem);
        elements=newdata;
        first_free=cap=dest;
    }

    StrVec(StrVec &&s) noexcept :elements(s.elements),first_free(s.first_free),cap(s.cap)
    {
        s.elements=s.first_free=s.cap=nullptr;
    }
    StrVec& operator=(StrVec &&rhs) noexcept
    {
        if(this!=&rhs)
        {
            free();
            elements=rhs.elements;
            first_free=rhs.first_free;
            cap=rhs.cap;
            rhs.elements=rhs.first_free=rhs.cap=nullptr;
        }
        return *this;
    }
    StrVec& operator=(initializer_list<string>);
    string& operator[](size_t n)
    {
        cout<<"[]"<<endl;
        return *(elements+n);
    }
    const string& operator[](size_t n) const
    {
        cout<<"const []"<<endl;
        return elements[n];
    }
private:
    static allocator<string> alloc;
    string *elements;
    string *first_free;
    string *cap;
    void chk_n_alloc()
    {
        if(size()==capacity()) reallocate();
    }
    pair<string*,string*> alloc_n_copy(const string*,const string*);
    void free();
    void reallocate();
};
bool operator==(const StrVec&,const StrVec&);
bool operator!=(const StrVec&,const StrVec&);
// emplace member covered in chapter 16
template <class... Args>
inline
void StrVec::emplace_back(Args&&... args)
{
    chk_n_alloc(); // reallocates the StrVec if necessary
    alloc.construct(first_free++, std::forward<Args>(args)...);
}
#endif // STRVEC_H

StrVec.cpp

#include"StrVec.h"
#include<algorithm>

allocator<string> StrVec::alloc;

StrVec::StrVec(const StrVec &s)
{
    auto newdata=alloc_n_copy(s.begin(),s.end());
    elements=newdata.first;
    first_free=newdata.second;
    cap=newdata.second;
}

StrVec& StrVec::operator=(const StrVec &s)
{
    auto data=alloc_n_copy(s.begin(),s.end());
    free();
    elements=data.first;
    first_free=cap=data.second;
    return *this;
}

StrVec& StrVec::operator=(initializer_list<string> il)
{
    auto data=alloc_n_copy(il.begin(),il.end());
    free();
    elements=data.first;
    first_free=cap=data.second;
    return *this;
}
StrVec::~StrVec() noexcept
{
    free();
}

void StrVec::push_back(const string &s)
{
    chk_n_alloc();
    alloc.construct(first_free++,s);
}

void StrVec::push_back(string&& s)
{
    chk_n_alloc();
    alloc.construct(first_free++,std::move(s));
}
pair<string*,string*> StrVec::alloc_n_copy(const string *b, const string *e)
{
    auto data=alloc.allocate(e-b);
    return {data,uninitialized_copy(b,e,data)};
}

void StrVec::free()
{
    if(elements)
    {
        //for_each(elements,first_free,[](string p) { alloc.destroy(&p);});
        for_each(&elements,&first_free,[](string *p) { alloc.destroy(p);});
        //for(auto p=first_free;p!=elements;)
          //  alloc.destroy(--p);
        alloc.deallocate(elements,cap-elements);
    }
}

void StrVec::reallocate()
{
    auto newcapacity=size()?2*size():1;
    auto newdata=alloc.allocate(newcapacity);
    auto dest=newdata;
    auto elem=elements;
   // auto last=uninitialized_copy(begin(),end(),newdata);
   //使用移动迭代器
    //auto last=uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),newdata);

    for(size_t i=0;i!=size();++i)
        alloc.construct(dest++,std::move(*elem++));
    free();
    elements=newdata;
    first_free=dest;
    cap=elements+newcapacity;
}

void StrVec::reserve(size_t n)
{
    if(capacity()<n)
        reallocate();
}

void StrVec::resize(size_t n,string s)
{
    if(size()<n)
        push_back(s);
    else if(size()>n)
    {
        for(auto p=elements+n;p!=first_free;)
            alloc.destroy(p++);
        first_free=elements+n;
    }
}
bool operator==(const StrVec& lhs,const StrVec& rhs)
{
    return lhs.elements==rhs.elements&&lhs.first_free==rhs.first_free&&lhs.cap==rhs.cap;
}

bool operator!=(const StrVec& lhs,const StrVec& rhs)
{
    return !(lhs==rhs);
}

main.cpp

#include <iostream>
#include"StrVec.h"
using namespace std;

void print(const StrVec &svec)
{
    cout<<"print"<<endl;
    for (auto it : svec)
        cout << it << " " ;
    cout <<endl;
}
int main()
{
    StrVec vec;  // empty StrVec
    string s = "some string or another";
    vec.push_back(s);      // calls push_back(const string&)
    vec.push_back("done"); // calls push_back(string&&)

    // emplace member covered in chpater 16
    s = "the end";
    vec.emplace_back("10"); // adds cccccccccc as a new last element
    vec.emplace_back(s);  // uses the string copy constructor
    string s1 = "the beginning", s2 = s;
    vec.emplace_back(s1 + s2); // uses the move constructor
    print(vec);
}

16.61定义你自己版本的make_shared。

#include<iostream>
#include<memory>
#include<string>
using namespace std;

template <typename T,typename... Args>
shared_ptr<T>Make_shared(Args&&... args)
{
   return make_shared<T>(std::forward<Args>(args)...);
}

int main()
{
    auto p=Make_shared<int>(1);
    cout<<*p<<endl;
    auto pp=Make_shared<string>(10,‘c‘);
    cout<<*pp<<endl;
}
时间: 2024-11-09 02:04:12

转发参数包的例子的相关文章

LoadRunner例子:检查点为参数的一个例子

LoadRunner例子:检查点为参数的一个例子 检查点是LoadRunner的一个功能,用来验证业务功能的正确性.如果检查的内容是变化的,脚本该如何写呢? 问题提出:LoadRunner订票网站例子中,创建一个虚拟用户脚本,在登陆完成之后,设立一个检查点,来检查"welcome, xxx".其中xxx为登陆的用户名称. 解决方法: 1)使用web_find() 做检查点 Action(){ //连接字符串,把welcome和用户名组合成一个字符串 char teststring[10

第20课 可变参数模板(1)_模板参数包和函数参数包

1.  参数包(parameter pack) (1)模板参数包(以tuple为例):template<typename- Elements>class tuple ①Elements标识符的左侧使用了省略号,在C++11中Elements被称为"模板参数包",表示可以接受任意多个参数作为模板参数. ②编译器将多个模板参数打包成"单个"的模板参数包,如tuple<int, char, double>实例化模板类时,Element就是包含int

第21课 可变参数模板(2)_展开参数包

1. 可变参数模板函数 (1)递归函数方式展开参数包 ①一般需要提供前向声明.一个参数包的展开函数和一个递归终止函数. ②前向声明有时可省略,递归终止函数可以是0个或n个参数 (2)逗号表达式和初始化列表方式展开参数包 ①逗号表达式按顺序执行,返回最后一个表达式的值. ②initilizer_list可接受任意多个不同类型的参数. ③借助逗号表达式来展开包,并将返回的结果用于初始化initilizer_list. [编程实验]展开可变参数模板函数的参数包 #include <iostream>

nginx rewrite arg 带问号的地址转发参数处理?Nginx重定向的参数问题

Nginx重定向的参数问题 在给某网站写rewrite重定向规则时,碰到了这个关于重定向的参数处理问题.默认的情况下,Nginx在进行rewrite后都会自动添加上旧地址中的参数部分,而这对于重定向到的新地址来说可能是多余.虽然这也不会对重定向的页面显示结果造成多少影响,但当你注意到新地址中包含有多余的"?xxx=xxx"时,心里总还是会觉得不爽.而且可能影响到网站的搜索优化SEO.那么该如何来处理这部分的内容呢?看了下面两个简单的例子你就会明白了. 例如:把http://exampl

源码包安装-例子

源码包安装就是在官网下载源代码自己编译安装.例子:安装Nginx服务前提需要配置好编译安装环境yum install -y gcc gcc++ openssl openssl-devel官网地址:nginx.org找到nginx1.6.3版本并下载创建nginx的用户和组: #useradd nginx -s /sbin/nologin -M 参数讲解:-s是指定目录;/sbin/nologin目录的用户是无法登录的也是为了安全考虑:-M是不生成家目录了上传到指定目录:解压:进去解压后的目录:预

zedboard的板级支持包GPIO例子

板级支持包例子 xgpio_example.c This file contains a design example using the GPIO driver(XGpio) and hardware * device.  It onlyuses a channel 1 of a GPIO device. * * This example can be ran on the Xilinx ML300 boardusing the Prototype Pins & * LEDs of thebo

Java变长变量(类似ES6的剩余参数)应用例子

今天看代码的时候,看到一处如下: 第三个参数提示:...properties的写法有点类似之前看过的ES6语法的剩余参数,不知道java也有这玩意儿.搜了下,是jdk1.5的新特性:变长变量.有点孤陋! 百度知道解释: 其实这种定义就类似一个数据的定义,可以不用给它的长度加以限制,可以传入任意多个参数.比用数据更灵活一些,不会出现一些数组越界等的异常.如:getType(String ...values);调用时,可以getType("a","b","c&

Enumeration遍历http请求参数的一个例子

Enumeration<String> paraNames=request.getParameterNames(); for(Enumeration e=paraNames;e.hasMoreElements();){ String thisName=e.nextElement().toString(); String thisValue=request.getParameter(thisName); System.out.println(thisName+"------------

httpclient post请求例子(无参数名与带参数名的例子)

版本:4.1 带参数名的情况 HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); // httpPost.setHeader("Accept-Encoding", "gzip,deflate");//表示返回的数据是压缩的zip格式 String postParam = "";//请求的参数内容 List<NameVa