C++ 11向量具有新功能emplace_back.与push_back依赖于编译器优化以避免副本的情况不同,emplace_back使用完美转发将参数直接发送到构造函数以就地创建对象.在我看来,emplace_back一切都push_back可以做到,但有些时候它会做得更好(但从来没有更糟).
我有什么理由使用push_back?
首先,我知道这个问题,但我不相信我会问同样的事情.
我知道什么std::vector<T>::emplace_back 呢 -我明白我为什么会使用它了push_back().它使用可变参数模板,允许我将多个参数转发给新元素的构造函数.
但我不明白为什么C++标准委员会决定需要一个新的成员函数.为什么他们不能简单地扩展功能push_back().据我所见,push_back可以在C++ 11中重载:
template <class... Args>
void push_back(Args&&... args);
Run Code Online (Sandbox Code Playgroud)
这不会破坏向后兼容性,同时允许您传递N个参数,包括将调用正常rvalue或复制构造函数的参数.事实上,GCC C++ 11实现push_back()只需调用emplace_back:
void push_back(value_type&& __x)
{
emplace_back(std::move(__x));
}
Run Code Online (Sandbox Code Playgroud)
所以,我看到它的方式,没有必要emplace_back().他们需要添加的是一个重载,push_back()它接受可变参数,并将参数转发给元素构造函数.
我错了吗?有什么理由需要一个全新的功能吗?
我想知道两者之间有什么不同.我注意到emplace是c ++ 11的补充.那为什么要加?
emplace_back做以下事情时,我认为这将是胜利者:
v.push_back(myClass(arg1, arg2));
Run Code Online (Sandbox Code Playgroud)
因为emplace_back会在向量中立即构造对象,而push_back首先会构造一个匿名对象,然后将其复制到向量中.有关更多信息,请参阅此问
我决定将它们与一个由整数填充的向量进行比较.
这是实验代码:
#include <iostream>
#include <vector>
#include <ctime>
#include <ratio>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main() {
vector<int> v1;
const size_t N = 100000000;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
for(size_t i = 0; i < N; ++i)
v1.push_back(i);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
std::cout << "push_back took me " << time_span.count() << " seconds.";
std::cout << …Run Code Online (Sandbox Code Playgroud) 我试图在循环中创建一个空向量,并希望每次将某个元素读入该循环时向该向量添加一个元素.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<float> myVector();
float x;
while(cin >> x)
myVector.insert(x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但这给了我错误信息.
我试图做emplace_back一个std::vector<std::map<int, int>>,但找不到正确的语法来做到这一点.
#include<map>
#include<vector>
int main()
{
std::vector<std::map<int, int>> v;
std::map<int,int> a {{1,2}};
v.push_back({{1,2}});
v.emplace_back({1,2}); // error
v.emplace_back({{1,2}}); // error
v.emplace_back(({1,2})); // error
}
Run Code Online (Sandbox Code Playgroud)
push_back在这里工作,但不是emplace_back.我怎样才能emplace_back工作?
试图理解使用push()或emplace()for 之间的区别std::stack.
我在想,如果我创建一个std::stack<int>,那么我会使用push()因为整数是一种原始类型而且没有任何东西emplace()需要构造.
但是,如果我正在创建,std::stack<string>那么我会选择emplace()因为std::string是一个对象.
这是正确的用法吗?
基于在回答这些 问题 在这里,我知道这肯定是最好使用C++ 14的std::make_unique,而不是emplace_back(new X)直接.
那就是说,打电话是首选
my_vector.push_back(std::make_unique<Foo>("constructor", "args"));
Run Code Online (Sandbox Code Playgroud)
要么
my_vector.emplace_back(std::make_unique<Foo>("constructor", "args"));
Run Code Online (Sandbox Code Playgroud)
也就是说,我应该使用push_back或emplace_back何时添加std::unique_ptr构造的std::make_unique?
====编辑====
为什么?c:< - (微笑)
根据文件它:
当且仅当容器中没有具有等效键的元素时,才在容器中插入使用参数args构造的对象.
但是,可以插入到unordered_map中的唯一对象具有类型 std::pair<Key const, Mapped>(因为要插入的对象需要键和值),这已知具有正好两个参数的构造函数.那么为什么它使用可变函数形式呢?当然,我完全不了解这一点.
我正在查看关于multimap的MSDN文档,并发现它有一个成员函数multimap :: emplace().以下是该成员函数的示例.
int main( ) {
using namespace std;
multimap<int, string> m1;
pair<int, string> is1(1, "a");
m1.emplace(move(is1));
}
Run Code Online (Sandbox Code Playgroud)
看来,emplace()和move()是C++ 0x中.有人可以帮我解释一下吗?我读到了move(),但我真的不明白它做了什么(引擎盖下).