Namespaces
Variants
Views
Actions

Difference between revisions of "Template:cpp/container/emplace back"

From cppreference.com
m
 
(38 intermediate revisions by 12 users not shown)
Line 1: Line 1:
{{cpp/container/{{{1|}}}/title | emplace_back}}
+
{{#vardefine:cont|{{{1|vector}}}}}<!--
{{cpp/container/{{{1|}}}/sidebar}}
+
-->{{cpp/container/{{#var:cont}}/title|emplace_back}}
{{ddcl | notes={{mark c++11 feature}} |
+
{{cpp/container/{{#var:cont}}/navbar}}
 +
{{dcl begin}}
 +
{{dcl rev multi
 +
|since1=c++11|dcl1=
 
template< class... Args >
 
template< class... Args >
 
void emplace_back( Args&&... args );
 
void emplace_back( Args&&... args );
 +
|since2=c++17|notes2={{#ifeq:{{#var:cont}}|vector|{{mark constexpr since c++20}}}}|dcl2=
 +
template< class... Args >
 +
reference emplace_back( Args&&... args );
 
}}
 
}}
 +
{{dcl end}}
  
 +
Appends a new element to the end of the container. The element is constructed through {{lc|std::allocator_traits::construct}}, which typically uses placement-new to construct the element in-place at the location provided by the container. The arguments {{c|args...}} are forwarded to the constructor as {{c|std::forward<Args>(args)...}}.
  
 
+
{{cpp/container/note_iterator_invalidation|{{#var:cont}}|emplace_back}}
Appends a new element to the end of the container. The element is constructed in-place, i.e. no copy or move operations are performed. The constructor of the element is called with exactly the same arguments, as supplied to the function.
+
  
 
===Parameters===
 
===Parameters===
{{param list begin}}
+
{{par begin}}
{{param list item | args | arguments to forward to the constructor of the element}}
+
{{par|args|arguments to forward to the constructor of the element}}
{{param list end}}  
+
{{par hreq}}
 +
{{#switch:{{#var:cont}}|deque|list=
 +
{{par req named|T (the container's element type)|EmplaceConstructible}}
 +
|vector=
 +
{{par req named|T (the container's element type)|EmplaceConstructible|MoveInsertable}}
 +
}}
 +
{{par end}}  
  
 
===Return value===
 
===Return value===
(none)
+
{{rrev multi
 +
|until1=c++17|rev1=(none)
 +
|rev2=A reference to the inserted element.
 +
}}
  
 
===Complexity===
 
===Complexity===
Constant.
+
{{#ifeq:{{#var:cont}}|vector|Amortized constant.|Constant.}}
  
 +
===Exceptions===
 +
{{cpp/strong exception safety guarantee|plural=no}}
 +
{{#ifeq: {{#var:cont}}|vector|
 +
If the move constructor of {{tt|T}} is not {{c/core|noexcept}} and is not {{named req|CopyInsertable}} into {{c|*this}}, {{tt|vector}} will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.
 +
}}
 +
{{#ifeq:{{#var:cont}}|vector|
 +
 +
===Notes===
 +
Since reallocation may take place, {{tt|emplace_back}} requires the element type to be {{named req|MoveInsertable}} for vectors.
 +
}}
 
===Example===
 
===Example===
 +
{{example
 +
|The following code uses {{tt|emplace_back}} to append an object of type {{tt|President}} to a {{lc|std::{{#var:cont}}}}. It demonstrates how {{tt|emplace_back}} forwards parameters to the {{tt|President}} constructor and shows how using {{tt|emplace_back}} avoids the extra copy or move operation required when using {{lc|push_back}}.
 +
|code=
 +
#include <{{#var:cont}}>
 +
#include <cassert>
 +
#include <iostream>
 +
#include <string>
 +
 +
struct President
 +
{
 +
    std::string name;
 +
    std::string country;
 +
    int year;
 +
 
 +
    President(std::string p_name, std::string p_country, int p_year)
 +
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
 +
    {
 +
        std::cout << "I am being constructed.\n";
 +
    }
  
{{eq fun cpp | 1 =
+
    President(President&& other)
typedef std::tuple<std::string, std::string, int> president;
+
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
std::{{{1}}}<president> v;
+
    {
v.emplace_back("Franklin Delano", "Roosevelt", 1932);
+
        std::cout << "I am being moved.\n";
 +
    }
  
 +
    President& operator=(const President& other) = default;
 +
};
 +
 +
int main()
 +
{
 +
    std::{{#var:cont}}<President> elections;
 +
    std::cout << "emplace_back:\n";
 +
    auto& ref = elections.emplace_back("Nelson Mandela", "South Africa", 1994);
 +
    assert(ref.year == 1994 && "uses a reference to the created object (C++17)");
 +
 +
    std::{{#var:cont}}<President> reElections;
 +
    std::cout << "\npush_back:\n";
 +
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
 +
 +
    std::cout << "\nContents:\n";
 +
    for (President const& president: elections)
 +
        std::cout << president.name << " was elected president of "
 +
                  << president.country << " in " << president.year << ".\n";
 +
 +
    for (President const& president: reElections)
 +
        std::cout << president.name << " was re-elected president of "
 +
                  << president.country << " in " << president.year << ".\n";
 +
}
 +
|output=
 +
emplace_back:
 +
I am being constructed.
 +
 +
push_back:
 +
I am being constructed.
 +
I am being moved.
 +
 +
Contents:
 +
Nelson Mandela was elected president of South Africa in 1994.
 +
Franklin Delano Roosevelt was re-elected president of the USA in 1936.
 
}}
 
}}
  
 
===See also===
 
===See also===
 
+
{{dsc begin}}
{{dcl list begin}}
+
{{dsc inc|cpp/container/dsc push_back|{{#var:cont}}}}
{{dcl list template | cpp/container/dcl list push_back |{{{1|}}}}}
+
{{dsc inc|cpp/container/dsc emplace|{{#var:cont}}}}
{{dcl list end}}
+
{{dsc end}}

Latest revision as of 17:49, 29 August 2024

 
 
 
 
template< class... Args >
void emplace_back( Args&&... args );
(since C++11)
(until C++17)
template< class... Args >
reference emplace_back( Args&&... args );
(since C++17)
(constexpr since C++20)

Appends a new element to the end of the container. The element is constructed through std::allocator_traits::construct, which typically uses placement-new to construct the element in-place at the location provided by the container. The arguments args... are forwarded to the constructor as std::forward<Args>(args)....

If after the operation the new size() is greater than old capacity() a reallocation takes place, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise only the end() iterator is invalidated.

Contents

[edit] Parameters

args - arguments to forward to the constructor of the element
Type requirements
-
T (the container's element type) must meet the requirements of MoveInsertable and EmplaceConstructible.

[edit] Return value

(none)

(until C++17)

A reference to the inserted element.

(since C++17)

[edit] Complexity

Amortized constant.

[edit] Exceptions

If an exception is thrown for any reason, this function has no effect (strong exception safety guarantee). If the move constructor of T is not noexcept and is not CopyInsertable into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.

Notes

Since reallocation may take place, emplace_back requires the element type to be MoveInsertable for vectors.

[edit] Example

The following code uses emplace_back to append an object of type President to a std::vector. It demonstrates how emplace_back forwards parameters to the President constructor and shows how using emplace_back avoids the extra copy or move operation required when using push_back.

#include <vector>
#include <cassert>
#include <iostream>
#include <string>
 
struct President
{
    std::string name;
    std::string country;
    int year;
 
    President(std::string p_name, std::string p_country, int p_year)
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    {
        std::cout << "I am being constructed.\n";
    }
 
    President(President&& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being moved.\n";
    }
 
    President& operator=(const President& other) = default;
};
 
int main()
{
    std::vector<President> elections;
    std::cout << "emplace_back:\n";
    auto& ref = elections.emplace_back("Nelson Mandela", "South Africa", 1994);
    assert(ref.year == 1994 && "uses a reference to the created object (C++17)");
 
    std::vector<President> reElections;
    std::cout << "\npush_back:\n";
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
 
    std::cout << "\nContents:\n";
    for (President const& president: elections)
        std::cout << president.name << " was elected president of "
                  << president.country << " in " << president.year << ".\n";
 
    for (President const& president: reElections)
        std::cout << president.name << " was re-elected president of "
                  << president.country << " in " << president.year << ".\n";
}

Output:

emplace_back:
I am being constructed.
 
push_back:
I am being constructed.
I am being moved.
 
Contents:
Nelson Mandela was elected president of South Africa in 1994.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.

[edit] See also

adds an element to the end
(public member function of std::vector<T,Allocator>) [edit]
(C++11)
constructs element in-place
(public member function of std::vector<T,Allocator>) [edit]