当前位置:嗨网首页>书籍在线阅读

04-对C++98容器所做的修改

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

G.1.2 对C++98容器所做的修改

C++11对容器类的方法做了三项主要修改。

首先,新增的右值引用使得能够给容器提供移动语义(参见第18章)。因此,STL现在给容器提供了移动构造函数和移动赋值运算符,这些方法将右值引用作为参数。

其次,由于新增了模板类initilizer_list(参见第18章),因此新增了将initilizer_list作为参数的构造函数和赋值运算符。这使得可以编写类似于下面的代码:

vector<int> vi{100, 99, 97, 98};
vi = {96, 99, 94, 95, 102};

第三,新增的可变参数模板(variadic template)和函数参数包(parameter pack)使得可以提供就地创建(emplacement)方法。这意味着什么呢?与移动语义一样,就地创建旨在提高效率。请看下面的代码段:

class Items
{
    double x;
    double y;
    int m;
public:
    Items();                                    // #1
    Items (double xx, double yy, int mm); // #2
    ...
};
...
vector<Items> vt(10);
...
vt.push_back(Items(8.2, 2.8, 3)); //

调用insert()将导致内存分配函数在vt末尾创建一个默认Items对象。接下来,构造函数Items()创建一个临时Items对象,该对象被复制到vt的开头,然后被删除。在C++11中,您可以这样做:

vi.emplace_back(8.2, 2.8, 3);

方法emplace_back()是一个可变参数模板,将一个函数参数包作为参数:

template <class... Args> void emplace_back(Args&&... args);

上述三个实参(8.2、2.8和3)将被封装到参数args中。参数args被传递给内存分配函数,而内存分配函数将其展开,并使用接受三个参数的Items构造函数(#2),而不是默认构造函数(#1)。也就是说,它使用Items(args…),这里将展开为Items(8.2, 2.8, 3)。因此,将在矢量中就地创建所需的对象,而不是创建一个临时对象,再将其复制到矢量中。

STL在多个就地创建方法中使用了这种技术。