답변:
벡터에 3 개 이상의 항목이있는 경우 마지막 3 개 항목을 삭제하는 것은 간단합니다. pop_back을 3 번 사용하십시오.
#include <vector>
#include <iostream>
int main()
{
std::vector<float> v = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 3 && !v.empty(); ++i)
v.pop_back();
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
}
산출:
1 2
먼저, X.end()
벡터의 마지막 요소에 이터레이터를 반환하지 않고, 벡터의 마지막 요소를 지나서 요소에 대한 이터레이터를 반환합니다. 즉, 벡터가 실제로 소유하지 않은 요소입니다. X.erase(d)
프로그램 충돌로 삭제하십시오 .
대신 벡터에 3 개 이상의 요소가 포함 된 경우 다음을 수행 할 수 있습니다.
X.erase( X.end() - 3, X.end() );
대신 세 번째 마지막 요소로 이동 한 다음에 도달 할 때까지 모든 요소를 지 웁니다 X.end()
.
편집 : 그냥이 명확히하기 위해 X.end()
A는 LegacyRandomAccessIterator 유효하도록 지정되어 -
다른 반환 작업 LegacyRandomAccessIterator을 .
end()
from cppreference 의 정의 는 다음과 같습니다.
벡터 컨테이너의 과거 요소를 참조하는 반복자를 반환합니다.
약간 아래 :
그것은 어떤 요소도 가리 키지 않으므로 역 참조되지 않아야한다.
즉, 벡터에는 end ()가 가리키는 요소가 없습니다. erase () 메소드를 통해 요소 가 아닌 요소 를 역 참조 하면 벡터에 속하지 않는 메모리가 변경 될 수 있습니다. 따라서 추악한 일이 발생할 수 있습니다.
간격에 "낮음"값이 포함 되고 간격에서 제외 된 "높음"값과 함께 간격을 [낮음, 높음)으로 설명하는 것이 일반적인 C ++ 규칙 입니다.
당신은 사용할 수 있습니다 reverse_iterator
:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<float> X = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6};
// start the iterator at the last element
vector<float>::reverse_iterator rit = X.rbegin();
// repeat 3 times
for(size_t i = 0; i < 3; i++)
{
rit++;
X.erase(rit.base());
}
// display all elements in vector X
for(float &e: X)
cout << e << '\n';
return 0;
}
언급 할 것이 거의 없습니다 :
reverse_iterator rit
의 마지막 요소에서 시작합니다 vector X
. 이 위치를이라고 rbegin
합니다.erase
iterator
작업 하려면 클래식 이 필요합니다 . 우리는 rit
전화 를 통해 얻을 수 있습니다 base
. 그러나 새로운 반복자는 rit
앞으로 다음 요소를 가리 킵니다 .rit
전화하기 전에 사전을 진행 base
하고erase
또한 더 알고 싶다면 reverse_iterator
이 답변을 방문하십시오 .
질문에 대한 의견 (현재 삭제됨)은 "반복자를위한 연산자가 없습니다"라고 말했습니다. 그러나 다음 코드 는 표준을 또는로 설정하여 and 에서 모두 컴파일 하고 작동 합니다 .MSVC
clang-cl
C++17
C++14
#include <iostream>
#include <vector>
int main()
{
std::vector<float> X{ 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f };
for (auto f : X) std::cout << f << ' '; std::cout << std::endl;
std::vector<float>::iterator d = X.end();
X.erase(d - 3, d); // This strongly suggest that there IS a "-" operator for a vector iterator!
for (auto f : X) std::cout << f << ' '; std::cout << std::endl;
return 0;
}
에 제공되는 정의 operator-
는 다음과 같습니다 ( <vector>
헤더에서).
_NODISCARD _Vector_iterator operator-(const difference_type _Off) const {
_Vector_iterator _Tmp = *this;
return _Tmp -= _Off;
}
그러나 나는 C ++ 언어 변호사가 아니며 이것이 위험한 Microsoft 확장 중 하나 일 수 있습니다. 이것이 다른 플랫폼 / 컴파일러에서 작동하는지 알고 싶습니다.
-
해당 유형의 반복기에 대해 정의되어 있기 때문에 유효하다고 생각 합니다.
이 진술
if (i == 1) X.erase(d);
정의되지 않은 동작이 있습니다.
그리고이 문장은 마지막 요소 앞의 요소 만 제거하려고합니다.
else X.erase(d - i);
반복이 두 번만있는 루프가 있기 때문에
for (size_t i = 1; i < 3; i++) {
다음과 같은 것이 필요합니다.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<float> v = { 1, 2, 3, 4, 5 };
auto n = std::min<decltype( v.size() )>( v.size(), 3 );
if ( n ) v.erase( std::prev( std::end( v ), n ), std::end( v ) );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
프로그램 출력은
1 2
d
실제로 존재하지 않습니다. 의 끝을 찾기 위해서만 사용할 수있는 과거의 마지막 카나리아 값vector
입니다. 제거 할 수 없습니다. 다음으로 반복자를 지우 자마자 사라졌습니다. 를 포함하여 이후에는 안전하게 사용할 수 없습니다d - i
.