Max Truxa
Max Truxa

Reputation: 3478

vector.assign() with value in sequence

Is the following well-defined?

std::vector<std::string> v{"test"};
v.assign(1, v.at(0));

If the old sequence was destroyed before the new one is constructed the reference passed to assign would be invalidated and hence the program would be ill-formed.

Does the standard mention this case (the value being part of the old sequence) or something similar anywhere, making this construct well-formed? I couldn't find anything.

From the copy of Dinkumware's standard library implementation shipped with VS2010 (_Assign_n is what's called internally by assign):

void _Assign_n(size_type _Count, const _Ty& _Val)
{ // assign _Count * _Val
    _Ty _Tmp = _Val; // in case _Val is in sequence
    erase(begin(), end());
    insert(begin(), _Count, _Tmp);
}

The comment

in case _Val is in sequence

suggests that either the standard explicitly states that assigning an element that is part of the current sequence is well-formed, or that Dinkumware's implementation just tries to be smart ;)

Which one is it?

Upvotes: 11

Views: 312

Answers (2)

user657267
user657267

Reputation: 20990

This is undefined behaviour, the copied element cannot come from the container itself.

[sequence.reqmts] table 84 (draft n4606)

enter image description here

Upvotes: 9

Sam Varshavchik
Sam Varshavchik

Reputation: 118300

at() returns a reference to the existing value in the container. As such, this is undefined behavior.

You can make this well defined behavior simply by making a copy of it:

v.assign(1, (std::string)v.at(0));

Upvotes: 1

Related Questions