标准向量构造元素一次

时间:2013-09-18 00:37:50

标签: c++ c++11 vector

这是一个非常直截了当的问题。 有没有办法有一个向量并初始化一个元素而不构造然后复制它?

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是一个很好的方法。

4 个答案:

答案 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."

据我所知,它将直接在内存位置创建一个对象。返回值优化。临时不会被创建。

我错了吗?