这是一个非常直截了当的问题。 有没有办法有一个向量并初始化一个元素而不构造然后复制它?
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是一个很好的方法。
答案 0 :(得分:6)
您可以使用std::vector<...>::emplace()
,或者,如果要附加对象std::vector<...>::emplace_back()
,则可以使用push_back()
来构建对象。如果你必须使用C ++ 03,那么这个成员函数是不可用的。作为近似值,您可以swap()
和空对象,然后将BigType
std::vector<...>
放入相应的位置,假设您可以构造一个小的空对象。
请注意,如果您拥有大型对象,std::deque<...>
不一定是最佳数据结构:如果保留空间用完,则向量需要对周围的对象进行随机播放以创建新空间。您可能希望使用std::vector<...>
,因为它不会放置其对象(除非您插入到中间),同时具有与{{1}}类似的访问特征。
答案 1 :(得分:4)
使用C ++ 11,是的。
bigTypeVec.emplace_back(BigType());
以下是更多信息:
http://en.cppreference.com/w/cpp/container/vector/emplace_back
答案 2 :(得分:1)
“有没有办法让一个向量并初始化一个元素而不构造然后复制它?”
是
考虑将new作为一种机制来侧面使用复制赋值,并使用临时。
“有没有办法让矢量......”
可以使用使用默认构造函数创建的元素构建矢量。
我相信可以定义BigType,以便在bigTypeVec构造期间不需要元素初始化。通过这种方式,声明向量(甚至是一个简单的数组)将不会触发元素构造函数的工作。考虑这些:
vector<BigType> bigTypeVec;
或
BigType bigTypeVec[MAX_BigTypeVecSize];
请注意,数组需要BigType来提供默认构造函数(或者提供大量的大括号数组初始化)。
但是,我可以想象您可能会为每个BigType元素找到值,以指示它是否已初始化。
“并在不构造[temp]的情况下初始化一个元素然后将它复制[,temp,到vector]?”
然后可以使用Placement new构建对象到位。通过将您希望初始化的所需bigTypeVec元素的地址传递给placement 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()和re-impliments“push back”的最简单的类,或者可能是支持您需求的新方法。这些方法将寻找推回可能找到的向量元素,并使用与上面类似的贴图。
答案 3 :(得分:0)
你确定吗?
"This constructs a temp object, and then copies it to the new element."
据我所知,它将直接在内存位置创建一个对象。返回值优化。临时不会被创建。
我错了吗?