使用模板省略号参数模仿 STL 容器的 emplaceback

来源:互联网 发布:数据库储存的是 编辑:程序博客网 时间:2024/06/10 23:53

首先你得有个容器

那行吧,就封装一下 STL 的 vector
代码如下:

template <typename T>class MyVector {private:    std::vector<T> m_vector;};

其次你得有个对象

单身狗的悲哀,代码如下:

class Example {public:    Example(int i, int j, int k) {        m_i = i;        m_j = j;        m_k = k;        std::cout << "constructor" << std::endl;    }    Example(const Example& example) {        m_i = example.m_i;        m_j = example.m_j;        m_k = example.m_k;        std::cout << "copy constructor" << std::endl;    }    Example(Example&& example) : m_i(example.m_i),m_j(example.m_j),m_k(example.m_k) {        std::cout << "move constructor" << std::endl;    }private:    int m_i;    int m_j;    int m_k;};

这里在提供了自定义构造,拷贝构造,移动构造三种构造函数

最后你可以省略了

不管如何构造,构造的参数是不能少的,为了满足各种不同对象的构造函数,可以想到用泛型 typename T,这些构造函数可能有很多不同种类的参数,可以想到用模板省略参数 typename ... Args

那行吧,都想到这了,代码如下:

template <typename ... Args>void myEmplaceBack(Args ... args) {    m_vector.push_back(new T(args...));}

看不懂这里怎么用的去看函数的省略号参数和模板的省略号参数的使用,你得知道如何解参数包

注意了,这里用 new 语义在分配了堆空间,根据之前探究过的指针在容器中的生存周期的实验可以知道,这是不保险的操作

这里要么考虑用智能指针,要么考虑保存右值

保存右值:

template <typename ... Args>void myEmplaceBack(Args ... args) {    m_vector.push_back(std::move(T(args...)));}

使用移动语义保存这个右值到容器中,这里使用了 move 之后的 push_back 会自动使用 push_back 的右值版本,不信你试试

完整容器如下:

template <typename T>class MyVector {public:    template <typename ... Args>    void myEmplaceBack(Args ... args) {        m_vector.push_back(std::move(T(args...)));    }private:    std::vector<T> m_vector;};

测试代码:

int main(int argc, char* argv[]){    MyVector<Example> v_example;    v_example.myEmplaceBack(1,2,3);    return 0;}

运行结果

constructormove constructor

CSDN 辣鸡 MD 编辑器,无序列表格式全丢

原创粉丝点击