std::set::emplace(3)
π NAME π
std::set::emplace β okay so this is literally just std::set::emplace, bestie, it's the in-place insert era and we're here for it π
This page lives in the C++ Standard Library section of the manual (that's the (3) vibe, iykyk) β¨
β¨ Synopsis β¨
template< class... Args > (since C++11)
std::pair<iterator, bool> emplace( Args&&... args );
So what it does: it inserts a brand-new element into the container, constructed in-place with the args you hand it β but only if there's no element with that key already chillin' in there. No cap.
The constructor of the new element gets called with exactly the same arguments as you supplied to emplace, forwarded via std::forward<Args>(args).... Like, the whole friend group gets passed along π
Heads up though π β the element may be constructed even if there already is an element with the key in the container. In that case the newly constructed element gets destroyed immediately. It's giving "built different and then immediately unalived" ππ
Careful use of emplace lets the new element be constructed while avoiding unnecessary copy or move operations. That's the whole flex, honestly. Obsessed.
And the best part? No iterators or references are invalidated. Periodt. π«Ά
πΈ Parameters πΈ
argsβ the arguments you forward to the constructor of the element. Literally just passing the vibes straight through β¨
π¦ Return value π¦
A pair consisting of:
- an iterator to the inserted element (or, plot twist, to the element that prevented the insertion π), and
- a
boolvalue set totrueif and only if the insertion actually took place π
π₯ Exceptions π₯
If an exception is thrown for any reason, this function has no effect β that's the strong exception safety guarantee, and she ate that π β
β Complexity β
Logarithmic in the size of the container. Math girlie behaviour, respectfully π
π Example π
// Run this code
#include <chrono>
#include <cstddef>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <set>
class Dew
{
private:
int a, b, c;
public:
Dew(int _a, int _b, int _c)
: a(_a), b(_b), c(_c)
{}
bool operator<(const Dew& other) const
{
return (a < other.a) ||
(a == other.a && b < other.b) ||
(a == other.a && b == other.b && c < other.c);
}
};
constexpr int nof_operations{101};
std::size_t 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();
}
std::size_t 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 time_it(std::function<int()> set_test, std::string what = "")
{
const auto start = std::chrono::system_clock::now();
const auto the_size = set_test();
const auto stop = std::chrono::system_clock::now();
const std::chrono::duration<double, std::milli> time = stop - start;
if (!what.empty() && the_size)
std::cout << std::fixed << std::setprecision(2)
<< time << " for " << what << '\n';
}
int main()
{
time_it(set_insert, "cache warming...");
time_it(set_insert, "insert");
time_it(set_insert, "insert");
time_it(set_emplace, "emplace");
time_it(set_emplace, "emplace");
}
π Possible output π
630.58ms for cache warming...
577.16ms for insert
560.84ms for insert
547.10ms for emplace
549.44ms for emplace
(no promises, timings are timings bestie π)
π§ See also π§
emplace_hintβ constructs elements in-place using a hint (C++11) (public member function) π«insertβ inserts elements or nodes (since C++17) (public member function) π
That's the whole page, mwah π source and version realness: http://cppreference.com, dated 2024.06.10, filed under std::set::emplace(3). Go forth and emplace responsibly, bestie π«Άβ¨π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms