C++ STL中的 emplace

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_39088557/article/details/81381939

英文释义(以前还真的很少用到这个单词,但是经常在键入empty()函数的时候冒出来):

emplace 
英 [ɪm'pleɪs]   美 [ɪm'pleɪs]  
v. 放列,安置,安放;

相对于insert、push、push_back系列先构造临时变量再复制到目标位置,emplace直接在目标位置上构造了。而且emplace支持“变参模板”,也就是说,如果它的实例类的构造函数有多个参数,emplace也支持对应个数的参数,而且对于显式构造函数,也能直接传参数。

比如这个类,接受一个int型的构造函数

class EmplaceClass {
    int num;
public:
    /*explicit */EmplaceClass(int x = 0) :num(x) { cout << "Constructed.\n"; }
    EmplaceClass(const EmplaceClass& from) :num(from.num) { cout << "Copied.\n"; }
    ~EmplaceClass() {/* cout << "Destructed.\n"; */}
};

在主函数函数中调用时的测试,为了避免vector增长后会复制,所以分别各自的vector进行push_back和emplace_back

    vector<EmplaceClass> ecTest,pbTest;
    cout << "Now emplace one element:" << endl;
    ecTest.emplace_back(1);
    cout << "Now push back one element:" << endl;
    pbTest.push_back(1);

输出为

Now emplace one element:
Constructed.
Now push back one element:
Constructed.
Copied.

emplace操作少了一次复制

当构造函数为显示时

class EmplaceClass {
    int num;
public:
    explicit EmplaceClass(int x = 0) :num(x) { cout << "Constructed.\n"; }
    EmplaceClass(const EmplaceClass& from) :num(from.num) { cout << "Copied.\n"; }
    ~EmplaceClass() {/* cout << "Destructed.\n"; */}
};

编译器就会报错

加入移动构造函数

class EmplaceClass {
    int num;
    string str;
public:
    /*explicit*/ EmplaceClass(int x = 0,string s="") :num(x) ,str(move(s)){ cout << "Constructed.\n"; }
    EmplaceClass(const EmplaceClass& from) :num(from.num),str(move(from.str)) { cout << "Copied.\n"; }
    EmplaceClass(EmplaceClass && from) :num(from.num), str(move(from.str)) { cout << "Moved.\n"; }
    ~EmplaceClass() {/* cout << "Destructed.\n"; */}
};
    vector<EmplaceClass> ecTest,pbTest;
    cout << "Now emplace one element:" << endl;
    ecTest.emplace_back(1,"a");
    cout << "Now push back one element:" << endl;
    //EmplaceClass ec(1, "a");
    //pbTest.push_back(ec);//左值引用
    pbTest.push_back({ 1,"a"});//右值引用

输出为

Now emplace one element:
Constructed.
Now push back one element:
Constructed.
Moved.

其实看看C++17里面push_back函数的源码,就知道原因了:

void push_back(const _Ty& _Val)
		{	// insert element at end, provide strong guarantee
		emplace_back(_Val);
		}

void push_back(_Ty&& _Val)
		{	// insert by moving into element at end, provide strong guarantee
		emplace_back(_STD move(_Val));
		}

相当于先构建一个左值或者右值引用_Val,再调用emplace_back。

猜你喜欢

转载自blog.csdn.net/sinat_39088557/article/details/81381939