std::set emplace() 方法
- 自 C++11 起
// Non const version only
template< class... Args >
std::pair<iterator, bool> emplace( Args&&... args );
如果容器中不存在具有给定键的元素,则使用给定的 args
在原位构造新元素并将其插入到容器中。
谨慎使用 emplace 可以构造新元素,同时避免不必要的复制或移动操作。
新元素的构造函数会以与提供给 emplace 的参数完全相同的参数进行调用,这些参数通过 std::forward<Args>(args)...
进行转发。即使容器中已经存在具有该键的元素,也可能会构造该元素,在这种情况下,新构造的元素会立即被销毁。
参数
args
- 转发给元素构造函数的参数
返回值
返回一个 pair,其中包含指向插入元素的迭代器(如果未发生插入,则为已存在的元素),以及一个 bool
值,表示是否发生了插入(如果发生插入,则为 true
,否则为 false
)。
复杂度
对容器大小呈对数关系 - O(log size())。
异常
如果任何操作抛出异常,此函数不产生任何影响(强异常保证)。
示例
Main.cpp
#include <chrono>
#include <functional>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
class Dew
{
private:
int a;
int b;
int c;
public:
Dew(int _a, int _b, int _c)
: a(_a), b(_b), c(_c)
{}
bool operator<(const Dew &other) const
{
if (a < other.a)
return true;
if (a == other.a && b < other.b)
return true;
return (a == other.a && b == other.b && c < other.c);
}
};
const int nof_operations = 120;
int set_emplace() {
std::set<Dew> set;
for(int i = 0; i < nof_operations; ++i)
for(int j = 0; j < nof_operations; ++j)
for(int k = 0; k < nof_operations; ++k)
set.emplace(i, j, k);
return set.size();
}
int set_insert() {
std::set<Dew> set;
for(int i = 0; i < nof_operations; ++i)
for(int j = 0; j < nof_operations; ++j)
for(int k = 0; k < nof_operations; ++k)
set.insert(Dew(i, j, k));
return set.size();
}
void timeit(std::function<int()> set_test, std::string what = "") {
auto start = std::chrono::system_clock::now();
int setsize = set_test();
auto stop = std::chrono::system_clock::now();
std::chrono::duration<double, std::milli> time = stop - start;
if (what.size() > 0 && setsize > 0) {
std::cout << std::fixed << std::setprecision(2)
<< time.count() << " ms for " << what << '\n';
}
}
int main()
{
set_insert();
timeit(set_insert, "insert");
timeit(set_emplace, "emplace");
timeit(set_insert, "insert");
timeit(set_emplace, "emplace");
}
可能输出
638.45 ms for insert
619.44 ms for emplace
609.43 ms for insert
652.55 ms for emplace