转发参数包的例子

简介: 16.58 为你的StrVec类添加emplace_back函数。 StrVec.h(注意,函数模板和模板成员函数的定义和声明要放在一起,通常都放在头文件中) #ifndef STRVEC_H #define STRVEC_H #include #include #include ...

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;
}

 

相关文章
|
5天前
|
Python
Python动态IP代理防止被封的方法
Python动态IP代理防止被封的方法
|
6月前
|
前端开发 JavaScript
.net core 前端传递参数有值 后端接收到的数据却是null
1、问题分析 在做接口测试时,偶然出现了前端输出有值,但是后端断点调试时却出现接收参数总是为null的情况 2、解决办法 前端打印log,看前端的每一个传值的数据类型,与后端请求参数类进行认真的一一比对 小技巧: ① 直接打印调用接口的传参值的数据类型,例如 console.log(type of this.form.name) --string console.log(type of this.form.age) --number 打印的数据类型与后端接口的参数类比对,查出不对应的类型 ② 关于非必填的值,默认传值可能出现空字符串(' ')、NaN值(Not a Number
100 0
|
前端开发 数据库
转发和重定向的区别及使用方法(全)
目录前言1. 定义1.1 转发1.2 重定向2. springmvc实战代码3. 总结异同 前言 页面跳转的主要两种实现方式: 转发 重定向 1. 定义 1.1 转发 在客户端中发送请求到服务端,在服务端中有所匹配的servlet即可,之后servlet执行其操作,之后调用getRequestDispacther()方法,把请求转发给指定的前端页面,整个流程都是在服务端中执行(同一个请求)。在转发过程中,可以把数据保存到request域对象中(因为转发使用同一个request域) request.get
205 0
|
数据库
转发和重定向的区别以及适用范围
一:请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作。 1.请求转发(forward)的特点: (1)浏览器的地址栏不会发生变化 (2)一次请求,服务器完成转发操作 (3)共享request域中的数据 (4)可以转发到WEB-INF目录下 (5)转发只能访问当前服务器下的资源
|
网络协议 物联网
DFP 数据转发协议应用实例 4.修改网络中指定设备的参数
稳控科技编写的一套数据转发规则, 取自“自由转发协议 FFP(Free Forward Protocol)” ,或者 DFP(DoubleF Protocol), DF 也可以理解为 Datas Forward(数据转发)的缩写。DF 协议是与硬件接口无关的数据链路层协议,规定了数据流如何在不同设备之间、不同接口之间的传输方向。 DF 协议一般用于延长数字接口的传输距离(数据中继),它与硬件接口类型无关,可以基于 UART、 LoRA、TCP 等异步数据传输介质。
DFP 数据转发协议应用实例  4.修改网络中指定设备的参数
|
SQL Java 数据安全/隐私保护
如何实现ip地址拉黑(过滤器类)
如何实现ip地址拉黑(过滤器类)
如何实现ip地址拉黑(过滤器类)
|
小程序
小程序路由传参案例
小程序路由传参案例
87 0
|
前端开发 PHP
无参数名post数据客户端以及接口是如何实现的?
无参数名post数据客户端以及接口是如何实现的?
210 0
|
开发者 Python
路由请求方式限定 | 学习笔记
快速学习路由请求方式限定

热门文章

最新文章