Namespaces
Variants
Views
Actions

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

From cppreference.com
m (Text replace - "{{concept" to "{{named req")
m
 
(15 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{cpp/container/{{{1|}}}/title | emplace_back}}
+
{{#vardefine:cont|{{{1|vector}}}}}<!--
{{cpp/container/{{{1|}}}/navbar}}
+
-->{{cpp/container/{{#var:cont}}/title|emplace_back}}
 +
{{cpp/container/{{#var:cont}}/navbar}}
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl | since=c++11 | until=c++17 |
+
{{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=
{{dcl | since=c++17 |
+
 
template< class... Args >
 
template< class... Args >
 
reference emplace_back( Args&&... args );
 
reference emplace_back( Args&&... args );
Line 12: Line 13:
 
{{dcl end}}
 
{{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 {{tt|args...}} are forwarded to the constructor as {{c|std::forward<Args>(args)...}}.
+
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|{{{1|}}}|emplace_back}}
+
{{cpp/container/note_iterator_invalidation|{{#var:cont}}|emplace_back}}
  
 
===Parameters===
 
===Parameters===
 
{{par begin}}
 
{{par begin}}
{{par | args | arguments to forward to the constructor of the element}}
+
{{par|args|arguments to forward to the constructor of the element}}
 
{{par hreq}}
 
{{par hreq}}
{{#switch:{{{1|}}}|deque|list=
+
{{#switch:{{#var:cont}}|deque|list=
{{par req concept | T (the container's element type) | EmplaceConstructible}}
+
{{par req named|T (the container's element type)|EmplaceConstructible}}
 
|vector=
 
|vector=
{{par req concept | T (the container's element type) | EmplaceConstructible | MoveInsertable}}
+
{{par req named|T (the container's element type)|EmplaceConstructible|MoveInsertable}}
 
}}
 
}}
 
{{par end}}  
 
{{par end}}  
  
 
===Return value===
 
===Return value===
{{rev begin}}
+
{{rrev multi
{{rev | until=c++17 | (none)}}
+
|until1=c++17|rev1=(none)
{{rev | since=c++17 | A reference to the inserted element.}}
+
|rev2=A reference to the inserted element.
{{rev end}}
+
}}
  
 
===Complexity===
 
===Complexity===
{{#ifeq:{{{1|}}}|vector|Amortized constant.|Constant.}}
+
{{#ifeq:{{#var:cont}}|vector|Amortized constant.|Constant.}}
  
 
===Exceptions===
 
===Exceptions===
If an exception is thrown, this function has no effect (strong exception guarantee).
+
{{cpp/strong exception safety guarantee|plural=no}}
{{#ifeq: {{{1|}}} | vector |
+
{{#ifeq: {{#var:cont}}|vector|
If {{tt|T}}'s move constructor is not {{c|noexcept}} and is not {{named req|CopyInsertable}} into {{tt|*this}}, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.
+
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:{{{1|}}}|vector|
+
{{#ifeq:{{#var:cont}}|vector|
  
 
===Notes===
 
===Notes===
The specialization [[cpp/container/vector_bool|std::vector<bool>]] did not have {{tt|emplace_back()}} member until C++14.
+
Since reallocation may take place, {{tt|emplace_back}} requires the element type to be {{named req|MoveInsertable}} for vectors.
 
+
 
}}
 
}}
 
===Example===
 
===Example===
 
{{example
 
{{example
| The following code uses {{tt|emplace_back}} to append an object of type {{tt|President}} to a {{c|std::{{{1}}}}}. 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 {{tt|push_back}}.
+
|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 =
+
|code=
#include <{{{1}}}>
+
#include <{{#var:cont}}>
 +
#include <cassert>
 +
#include <iostream>
 
#include <string>
 
#include <string>
#include <iostream>
 
 
   
 
   
 
struct President
 
struct President
Line 66: Line 67:
 
         std::cout << "I am being constructed.\n";
 
         std::cout << "I am being constructed.\n";
 
     }
 
     }
 +
 
     President(President&& other)
 
     President(President&& other)
 
         : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
 
         : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
Line 71: Line 73:
 
         std::cout << "I am being moved.\n";
 
         std::cout << "I am being moved.\n";
 
     }
 
     }
 +
 
     President& operator=(const President& other) = default;
 
     President& operator=(const President& other) = default;
 
};
 
};
Line 76: Line 79:
 
int main()
 
int main()
 
{
 
{
     std::{{{1}}}<President> elections;
+
     std::{{#var:cont}}<President> elections;
 
     std::cout << "emplace_back:\n";
 
     std::cout << "emplace_back:\n";
     elections.emplace_back("Nelson Mandela", "South Africa", 1994);
+
     auto& ref = elections.emplace_back("Nelson Mandela", "South Africa", 1994);
 +
    assert(ref.year == 1994 && "uses a reference to the created object (C++17)");
  
     std::{{{1}}}<President> reElections;
+
     std::{{#var:cont}}<President> reElections;
 
     std::cout << "\npush_back:\n";
 
     std::cout << "\npush_back:\n";
 
     reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
 
     reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));
 
   
 
   
 
     std::cout << "\nContents:\n";
 
     std::cout << "\nContents:\n";
     for (President const& president: elections) {
+
     for (President const& president: elections)
 
         std::cout << president.name << " was elected president of "
 
         std::cout << president.name << " was elected president of "
 
                   << president.country << " in " << president.year << ".\n";
 
                   << president.country << " in " << president.year << ".\n";
    }
+
 
     for (President const& president: reElections) {
+
     for (President const& president: reElections)
 
         std::cout << president.name << " was re-elected president of "
 
         std::cout << president.name << " was re-elected president of "
 
                   << president.country << " in " << president.year << ".\n";
 
                   << president.country << " in " << president.year << ".\n";
    }
 
 
}
 
}
| output=
+
|output=
 
emplace_back:
 
emplace_back:
 
I am being constructed.
 
I am being constructed.
Line 108: Line 111:
  
 
===See also===
 
===See also===
 
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/container/dsc push_back |{{{1|}}}}}
+
{{dsc inc|cpp/container/dsc push_back|{{#var:cont}}}}
 +
{{dsc inc|cpp/container/dsc emplace|{{#var:cont}}}}
 
{{dsc 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]