跳到主要内容

std::set emplace() 方法

// 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
本文源自此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”以查看本文档的所有更改。
悬停查看原始许可证。

std::set emplace() 方法

// 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
本文源自此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”以查看本文档的所有更改。
悬停查看原始许可证。