1

这是一个非常直接的问题。有没有办法在不构造然后复制它的情况下拥有一个向量并初始化一个元素?

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

4 回答 4

6

您可以使用std::vector<...>::emplace()or,如果您想附加对象,std::vector<...>::emplace_back()则在适当位置构造对象。如果您必须使用 C++03,则此成员函数不可用。作为近似值,您可以清空push_back()对象,然后进入相应的位置,假设您可以构造一个小的空对象。swap()BigType

请注意,std::vector<...>如果您有巨大的对象,这不一定是最好的数据结构:如果保留空间用完,则向量需要将对象打乱以腾出新空间。您可能想要使用std::deque<...>它,因为它不会将其对象放置(除非您插入中间),同时具有与std::vector<...>.

于 2013-09-18T00:42:41.667 回答
4

使用 C++11,是的。

bigTypeVec.emplace_back(BigType());

这里有更多信息:

http://en.cppreference.com/w/cpp/container/vector/emplace_back

于 2013-09-18T00:41:26.130 回答
1

“有没有办法在不构造然后复制它的情况下拥有一个向量并初始化一个元素?”

是的。

考虑将放置新位置作为回避使用复制分配及其使用临时的机制。


“有没有办法拥有一个向量……”

可以使用使用默认构造函数创建的元素来构建向量。

我相信可以定义 BigType 以便在 bigTypeVec 构造过程中不需要元素初始化。这样,声明向量(甚至是简单的数组)将不会触发任何元素构造函数的工作。考虑这些:

vector<BigType>  bigTypeVec;

或者

BigType  bigTypeVec[MAX_BigTypeVecSize];

请注意,该数组需要 BigType 提供默认构造函数(或者您提供一大堆花括号数组初始化)。

但是,我可以想象您可能会找到每个 BigType 元素的值来指示它是否已初始化。


“并在不构造 [a temp] 的情况下初始化元素,然后将其复制 [,temp,到向量]?”

然后可以使用 Placement 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() 并重新实现“推回”,或者可能是支持您需求的新方法。这些方法将寻找 push-back 找到的向量元素,并使用与上述类似的放置 new。

于 2013-09-18T02:59:20.810 回答
0

你确定吗?

    "This constructs a temp object, and then copies it to the new element."

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

我错了吗?

于 2013-09-18T00:46:47.030 回答