这两个 std::vector 的赋值方法有什么区别?



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

std::vector<std:string> vectorOne, vectorTwo;
// fill vectorOne with strings
// First assign method
vectorTwo = vectorOne;
// Second assign method
vectorTwo.assign( vectorOne.begin(), vectorOne.end() );

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

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

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.

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

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

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

在这种情况下它们是等价的。[和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=采用单个右手操作数,所以在需要默认参数值或值范围时使用assignassign的作用可以通过首先创建合适的向量,然后分配来间接完成

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

然而,这可能既丑陋又低效(例子取自Bjarne Stroustrup的"C++…")

还要注意,如果矢量不是同一类型的,那么还需要允许隐式转换的assign

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

最新更新