2015-03-05 5 views
1

Разница между следующими? Какой из них имеет неопределенное поведение? И то и другое?Разница между copy_n и копией

std::copy_n(asdf.begin(), asdf.size(), asdf.begin()); 
std::copy(asdf.begin(), asdf.end(), asdf.begin()); 

Предположим, std::vector<int> дано функции. И эти две функции не такие, как говорят некоторые люди.

Это дефект в стандарте?

+2

Оба они могут иметь неопределенное поведение. Один экземпляр по количеству, другой по диапазону. –

+1

Какое из перечисленных выше имеет неопределенное поведение? Не только функции. – user4634678

+0

Если вы указали размер, превышающий размер вашей памяти, 'copy_n' будет иметь неопределенное поведение. Если итераторы 'end()' или 'begin()' 'в' copy' находятся вне границ, вы будете иметь неопределенное поведение. Это и то, и другое, в зависимости от значений, предоставляемых функциям. –

ответ

5
std::copy_n(asdf.begin(), asdf.size(), asdf.begin()); 

Это не неопределенное поведение. copy_n требует только то, что [first, first + n) и [result, result + n) действительны. С аргументами, которые вы прошли, вы гарантировали, что они есть. (Я предполагаю, asdf представляет собой стандартный контейнер или контейнер с подобным поведением. Я также при условии, что содержащиеся типа имеет хорошо вели себя оператор присваивания)

std::copy(asdf.begin(), asdf.end(), asdf.begin()); 

Это поведение не определено. Для std::copy, result не должно быть в диапазоне [first, last)

+0

Вы говорите, что 'copy_n' может самокопировать, но' copy' не может? Я этого не знал. Почему это? –

+0

@NeilKirk: Я не знаю почему. Но это то, что говорит стандарт. 'copy' перечисляет это требование напрямую, а' copy_n' - нет. –

+0

@NeilKirk Потому что стандартный (* [alg.copy] *) говорит так? Возможно, что 'copy' может делегировать' memcpy' для тривиально-копируемых типов. Там 'copy_backward', если вы хотите перекрывать диапазоны, где начало выходного диапазона перекрывает диапазон источника, который нужно обрабатывать. – Praetorian