【发布时间】:2018-01-09 05:45:21
【问题描述】:
我想知道std::vector 的emplace_back 和push_back 方法在使用原始标量类型(例如std::uint32_t 或std::uint8_t)时是否有任何不同。直觉上,我猜想,在编译之后,这两种变体都会在此处产生相同的字节码:
void copyListContent(std::uint8_t * list, std::size_t nElems,
std::vector<std::uint8_t> & vec)
{
vec.clear();
vec.reserve(nElems);
for (std::size_t i = 0; i < nElems; ++i)
{
//variant 1:
vec.push_back(list[i]);
//variant 2:
vec.emplace_back(list[i]);
}
}
如果这已经是错误的,请纠正我......
现在,当我问自己如果“列表”和向量的类型不匹配时会发生什么时,我开始挣扎:
void copyListContent(std::uint8_t * list, std::size_t nElems,
std::vector<std::uint32_t> & vec)
{
//... same code as above
}
std::uint8_t 元素在放入向量时将被转换为std::uint32_t(使用emplace_back 或push_back),所以我想知道这是否会触发一些“构造函数”被调用?在那种情况下,emplace_back 会更有效吗,因为它会避免构造一个将被复制的临时对象?还是这些隐式转换没有任何区别,emplace_back 和 push_back 的行为会相同?
所以,我问自己和你:
对于此类原始类型,emplace_back 和 push_back 的行为是否总是相似?
作为一个模糊的猜测,我会说“可能是的”,但我对 C++ 内部的了解不足,无法为自己可靠地回答这个问题。我很乐意了解这种情况下的工作原理 - 非常感谢!
【问题讨论】:
-
我很乐意了解它的工作原理 - 首先:编译器非常聪明。
-
这很好,但不是每个人都会接受的论点 :-) 假设你有人告诉你“应该使用 emplace_back,它更有效”......编译器也只是人造的,并且必须有人能够判断对于这些情况,两个函数是否会“总是”产生相同的字节码,或者“不总是”,或者“理论上不总是,但在实践中总是”;-)