Ответ 1
Это поведение undefined, скопированный элемент не может поступать из самого контейнера.
[sequence.reqmts] таблица 84 (черновик n4606)
Являются ли следующие четко определенные?
std::vector<std::string> v{"test"};
v.assign(1, v.at(0));
Если старая последовательность была уничтожена до того, как будет построена новая
ссылка, переданная на assign
, будет признана недействительной, и, следовательно,
программа будет плохо сформирована.
Означает ли стандарт этот случай ( значение является частью старой последовательности) или что-то подобное в любом месте, что делает эту конструкцию хорошо сформированной? Я ничего не мог найти.
Из копии стандартной реализации библиотеки Dinkumware отправлено
с VS2010 (_Assign_n
- это то, что внутренне называется 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);
}
Комментарий
в случае, если _Val находится в последовательности
предполагает, что либо стандарт явно указывает, что назначение элемента, являющегося частью текущая последовательность хорошо сформирована или что реализация Dinkumware просто пытается быть умным;)
Какая из них?
Это поведение undefined, скопированный элемент не может поступать из самого контейнера.
[sequence.reqmts] таблица 84 (черновик n4606)
at()
возвращает ссылку на существующее значение в контейнере. По существу, это поведение undefined.
Вы можете сделать это четко определенное поведение, просто сделав его копию:
v.assign(1, (std::string)v.at(0));