Ele*_*ntW 21 c++ stl return-value c++11
当使用std::vectors,std::lists(或其他STL容器)时,我碰巧经常写这个,因为代码短缺(而不是vec[index]每次都显式)和内存分配效率(避免复制/移动),我想我不是只有一个这样做:
std::vector<A> vec;
vec.emplace_back();
A &element = vec[vec.size()-1];
element.prop = "value";
Run Code Online (Sandbox Code Playgroud)
为什么不STL容器emplace,emplace_back而emplace_front方法返回一个T&?这将允许一个人简单地写这个而不是使用阴影vec.size()-1:
std::vector<A> vec;
A &element = vec.emplace_back();
element.prop = "value";
Run Code Online (Sandbox Code Playgroud)
Joh*_*åde 21
这已在C++ 17中修复.你的榜样
std::vector<A> vec;
A &element = vec.emplace_back();
element.prop = "value";
Run Code Online (Sandbox Code Playgroud)
是有效的C++ 17代码.
qua*_*dev 11
您有成员方法来访问这些对象,因为您知道它们的插入位置.即front()和back().
一些其他函数(例如map::insert)将返回迭代器,因为您不知道如何在恒定时间内访问插入的元素.在这种情况下emplace,你知道.
不返回任何内容的另一个原因可能是性能(大多数情况下您不会使用返回的值).在C++中,您需要为使用的内容付费.
选择此签名的两个参数:
API对称性.这些API与pop_back,pop_front以及为队列实现的push和pop对称.这些函数(pop函数)有一种情况,即元素在异常存在时可能会丢失(即元素从集合中删除,但在返回之前发生异常(例如,如果对象的构造函数可以抛出).
通过将此功能(读取元素和pop元素)实现为两个单独的函数,两者都可以以事务方式实现.
SRP.这是一个很好的设计指导,如果你描述一个函数的行为,并需要使用"和"字,你已经打破SRP和它应该有两种可能分裂(即A功能"的结尾追加一个元素和返回对它的引用"应该写成两个函数"在末尾添加一个元素"和"在末尾添加返回元素" - 这两个函数都可以为客户端代码提供至少弱异常保证.
我不确定这些标准是否适用于设计,但我记得在关于异常安全的讲座中给出的异常保证参数.
你不需要它.写这个:
template<class C, class...Args>
auto emplace_back(C& c, Args&&...args)->decltype(c.back()){
c.emplace_back(std::forward<Args>(args)...);
return c.back();
}
Run Code Online (Sandbox Code Playgroud)
并且您拥有所需的语义,而无需修改容器界面.
只是:
emplace_back(vec).prop = "foo";
Run Code Online (Sandbox Code Playgroud)