这是一个非常简单的问题。有没有办法拥有一个向量并初始化一个元素,而无需构造然后复制它?
class BigType
{
// has a costly copy constructor
};
int main(void)
{
using std::vector;
vector<BigType> bigTypeVec;
bigTypeVec.push_back(BigType(/*constructor from parameters*/));
// This constructs a temp object, and then copies it to the new element.
}
当然,有各种各样的工作涉及指针向量,或者不使用构造函数,而是使用 set 函数初始化元素的组件,但是我想知道是否有一种方法可以做到这一点,以便它可以在push_back期间分配的元素上调用构造函数。
编辑:这个问题被标记为重复,但是我查看了该页面,他的问题的答案没有回答我的。我想知道如何通过构造一次来设置元素的值,而不是将构造临时对象复制到元素中。Emplace是一个很好的方法。
您可以使用std::vector<...>::emplace()
或者,如果要附加对象,可以使用std::vector<...>::emplace_back()
,就地构造对象。如果必须使用 C++03,则此成员函数不可用。作为近似值,您可以push_back()
并清空对象,然后将BigType
swap()
到相应的位置,假设您可以构造一个小的空对象。
请注意,如果你有巨大的对象,std::vector<...>
不一定是最好的数据结构:如果保留的空间用完了,向量需要打乱对象以创建新空间。您可能希望改用std::deque<...>
,因为它不会保留其对象(除非您插入中间),同时具有与std::vector<...>
类似的访问特征。
C++11,是的。
bigTypeVec.emplace_back(BigType());
以下是更多信息:
http://en.cppreference.com/w/cpp/container/vector/emplace_back
"有没有办法拥有一个向量并初始化一个元素,而无需构造然后复制它?"
是的。
考虑将放置 new 作为一种机制来回避使用副本分配,并且它是使用临时分配。
"有没有办法有一个载体..."
可以使用使用默认构造函数创建的元素构建向量。
我相信可以定义 BigType,以便在 bigTypeVec 构造过程中不需要元素初始化。这样,声明向量(甚至是一个简单的数组)将不会触发任何元素构造函数工作。 考虑这些:
vector<BigType> bigTypeVec;
或
BigType bigTypeVec[MAX_BigTypeVecSize];
请注意,数组需要 BigType 提供默认构造函数(或者您需要提供一大堆大括号数组初始化)。
但是,我可以想象您可能会发现每个 BigType 元素的值都指示它已初始化或未初始化。
"并在不构造 [temp] 的情况下初始化一个元素,然后将其 [,temp,复制到向量]?
然后,可以使用放置 new 来就地构造对象。通过将您希望初始化的所需 bigTypeVec 元素的地址传递给放置 new,所有元素构造函数工作都将发生在您想要的位置(在内存中)。 考虑如下内容:
vector<BigType> bigTypeVec;
BigType* pBT = 0;
pBT = new (&bigTypeVec[0] BigType(<param>); // placement new
pBT = new (&bigTypeVec[1] BigType(<param>);
...
pBT = new (&bigTypeVec[n] BigType(<param>);
请注意丢弃 pBT。 不使用指针。
*"我想知道是否有办法做到这一点,以便它可以在push_back期间分配的元素上调用构造函数。"*
此时,剩下的就是创建从 std::vector() 继承的最简单的类,并重新暗示"推回",或者可能是支持您需求的新方法。 这些方法将寻找回推会找到的矢量元素,并使用类似于上面的新放置。
你确定吗?
"This constructs a temp object, and then copies it to the new element."
据我所知,它会直接在内存位置创建一个对象。返回值优化。不会创建临时。
我错了吗?