I'm confused by the syntax of some C concepts.
Let's say I have a vector of vector:
vector<vector<int>> data;
I can use push_back()
to insert a new element:
data.push_back({1, 1});
In this way, I list initialized a new element, then a copy of this element is pushed to data
?
I can also do it in this way:
vector<int> tmp{1, 1};
data.emplace_back(tmp);
But if I directly call emplace()
, like in this way:
data.emplace_back(1, 1);
It does not give me the expected result.
Did I misunderstand something here?
---update:
sorry, what I mean is emplace_back
. My question is how to initialize directly using emplace_back
instead of initializing a tmp vector first, vector<int> tmp{1, 1};
.
CodePudding user response:
I can use push_back to insert a new element: data.push_back({1, 1}); In this way, I list initialized a new element, then a copy of this element is pushed to data?
exactly.
data.emplace(1, 1);
vector<Type>::emplace_back
forwards its arguments to the constructor of Type
. Now, std::vector<int>
has a constructor that takes two integer arguments! The one specifying length (1) and fill element (1).
You can, however, inform the compiler you actually mean list initialization!
#include "fmt/format.h"
#include "fmt/ranges.h"
#include <initializer_list>
#include <vector>
int main() {
std::vector<std::vector<int>> a;
a.emplace_back(std::initializer_list<int>{1, 1});
a.emplace_back(std::initializer_list<int>{2, 2});
fmt::print("{}\n", fmt::join(a.begin(), a.end(), ";"));
}
yields the expected
{1, 1};{2, 2}
To show it really does the in-place construction: Follow this link to gcc.godbolt.org, and observe how push_back({3,3,3,3});
actually calls the vector<int>
constructor and then the insert
of the vector<vector>
, while emplace_back
really just calls the initializer-list constructor.
CodePudding user response:
There is an emplace function, but this takes an iterator (see docs).
emplace_back
will add a new element to the end of the vector.
emplace
emplaces the element at a specified a position indicated by an iterator. v.emplace_back(1)
and v.emplace(v.end(), 1)
are the same, because the indicated position is the end of v
.