3

有两种方法(我知道)将一个向量分配给另一个向量:

std::vector<std:string> vectorOne, vectorTwo;
// fill vectorOne with strings

// First assign method
vectorTwo = vectorOne;

// Second assign method
vectorTwo.assign( vectorOne.begin(), vectorOne.end() );

当在非常大的向量上执行时,这些方法之间是否真的有区别,或者它们在效率和安全性方面是相等的?

4

3 回答 3

7

它们几乎是等价的。第二个原因是您可能有需要(隐式)转换的类型:

std::vector<int> vi;
std::vector<double> vd;
//  ...
vd.assign( vi.begin(), vi.end() );

或者容器的类型可能不同:

vd.assign( std::istream_iterator<double>( file ),
           std::istream_iterator<double>() );

如果你知道这两个容器是相同的类型,只需使用赋值。它的优点是仅使用对源的单个引用,并且可能允许 C++11 中的移动语义。

于 2013-08-28T16:03:25.097 回答
6

第二种形式是通用的,它适用于任何迭代器类型,并且只是从源向量中复制元素。

第一种形式只适用于完全相同类型的vector,它复制元素并且在 C++11 中也可能通过从源向量复制分配器来替换分配器。

在您的示例中,类型是相同的,并且使用std::allocator的是无状态的,因此没有区别。您应该使用第一种形式,因为它更简单、更易于阅读。

于 2013-08-28T16:05:04.807 回答
1

在这种情况下它们是等价的。[和 C++03 标准]。但是,如果 vectorTwo 在分配之前包含元素,则不同之处在于。然后

vectorTwo = vectorOne; // use operator=
// Any elements held in the container before the call 
// are either assigned to or destroyed.

vectorTwo.assign() // any elements held in the container
// before the call are destroyed and replaced by newly 
// constructed elements (no assignments of elements take place).

assign是必需的,因为operator=需要单个右手操作数,因此assign在需要默认参数值或值范围时使用。可以通过首先创建合适的向量然后分配它assign来间接完成什么:

void f(vector<Book>& v, list<Book>& l){
    vector<Book> vt = (l.begin(), l.end());
    v = vt;
}

然而,这可能既丑陋又低效(示例取自 Bjarne Stroustrup “The C++ ...”)

另请注意,如果 vector 不是同一类型,则还需要assignwhich 允许隐式转换:

vector<int> vi;
vector<double> vd;
//  ...
vd.assign( vi.begin(), vi.end() );
于 2013-08-28T16:07:46.673 回答