push_back()和resize(size()+ 1)之间有什么区别吗?

7 c++ stdvector

通过以下任一方式,可以扩展标准向量以容纳另一个成员:

std::vector<int> v;
v.push_back(1);
Run Code Online (Sandbox Code Playgroud)

要么

int os = v.size();
v.resize(os+1);
v[os] = 1;
Run Code Online (Sandbox Code Playgroud)

除了使用push_back()的代码的简洁性,还有其他差异吗?例如,一个比另一个更有效,还是在每种情况下分配不同的额外内存?

Pub*_*bby 8

push_back 将就地构造,这意味着它调用复制构造函数.

resize将调用默认构造函数,然后v[os]调用赋值运算符.

使用push_back.


正如Lightness所说,两种情况下的分配是相同的.有关详细信息,请参阅他的回答

这是一个例子:http://stacked-crooked.com/view?id = 43766666e5c72d282bd94c05e43e8897

  • 如果你包括在任何一种情况下的内存分配应该完全等效的事实+1. (2认同)

Lig*_*ica 5

内存扩展

但他们是否以同样的方式扩大记忆?

它没有在C++ 11中明确指定(我检查过),但是是的.

resize在这种情况下被定义为"附加到容器",其唯一的逻辑解释使其等同于insert并且push_back就分配而言.

容器实现的后端通常在其内存块扩展的情况下分配"超过它需要的数量" - 这是通过不禁止它而不是标准强制它的标准来完成的,并且没有措辞表明事实并非如此resize.

最终,这完全取决于实现,但我会惊讶地看到在任何主流编译器上两种方法之间的内存分配规则存在差异.

此测试用例显示了一个简单示例:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> a, b;

    for(int i = 0; i != 100; ++i)
      a.push_back(0);
    for(int i = 0; i != 100; ++i)
      b.resize(i+1);

    std::cout << a.capacity() << " , " << b.capacity() << std::endl;
}

// Output from my GCC 4.7.2:
//  128 , 128
Run Code Online (Sandbox Code Playgroud)

请注意,这个略有不同:

int main() {
    std::vector<int> a, b;

    for(int i = 0; i != 100; ++i)
      a.push_back(0);
    b.resize(100);

    std::cout << a.capacity() << " , " << b.capacity() << std::endl;
}

// Output from my GCC 4.7.2:
//  128 , 100
Run Code Online (Sandbox Code Playgroud)

这不是两种方法之间的公平测试,因为在后一示例中,我们以不同的增量扩展内存,并且内存后备序列容器趋向于以倍数扩展.


性能问题

无论如何,正如@Pubby所识别的那样,在resize你将进行隐式构造然后进行显式赋值的情况下,如果你过早地进行优化,那么这是非最优的.

在现实世界中,真正的问题是使用错误的函数来编写工作并编写愚蠢的代码.