※ 요약
std::vector의 멤버 함수인 emplace_back은 C++11부터 추가된 멤버 함수로써 push_back과 같이 vector의 요소 끝에 원소를 추가하는 함수이다. 두 함수의 가장 큰 차이점은, push_back과 같은 삽입 함수들은 삽입할 객체를 받지만 emplace_back과 같은 생성 삽입 함수는 삽입할 객체의 생성자를 위한 인자들을 받아 std::vector 내에서 직접 객체를 생성하여 삽입하므로 임시 객체의 생성과 파괴, 복사(혹은 move)를 하지 않아도 되어 성능상 더 유리하다는 것이다.
필자가 전에 작성한 push_back도 꼭 읽어보길 바란다.

※ 함수 원형

template< class... Args >

void emplace_back( Args&&... args );


emplace의 함수 원형은 하나다. push_back과 다르게 가변인자 템플릿 문법을 이용하여 가변인자를 받는다.


※ 예제

설명을 위해 아래와 같이 임시로 예제를 작성해봤다.


먼저 push_back으로 삽입을 했을때 결과이다. push_back에 삽입하기 위해 객체를 만들어 전달했고 내부적으로 또 임시객체를 만들어 아래와 같이 호출이 많아 성능상 불리하다.


emplace_back으로 삽입할 경우, 생성에 필요한 인자를 받아 내부에서 생성 삽입하므로 아래와 같이 생성자, 소멸자를 한 번씩만 호출하여 성능상 유리하다

.




※ 실제 사용예
필자가 전에 push_back으로 작성했던 코드이다. 이 코드는 CStationObj 임시 객체를 생성하고 그것을 push_back에 전달하는 걸 알 수 있으며 성능을 따져봤을때 비효율적이다.(내부적으로 CStationObj의 임시 객체가 생성되고 생성자와 소멸자도 호출되기 때문)


emplace_back은 함수 원형에서 본 거와 같이 가변 인자를 받을 수 있어서 아래와 같이 인자를 넣을 수 있으며, 받은 인자를 std::vector안에서 직접 CStationObj를 생성하므로 push_back보다 성능상 낫다.


※ 참고 사항

- push_back으로 하여도 컴파일러 내부적으로 최적화 하기 때문에 emplace_back으로 하는 것과 별차이가 없을 수 있다. 고로 개인 프로젝트가 아니라면 호환성이 더 좋은 push_back 사용이 더 나을 수도 있다.

- push_back함수로 할 수 있는 모든 것을 emplace_back으로 할 수 있다.

- push_back함수보다 emplace_back 함수가 대체로 효율적이다.(무조건적인건 아님 반대로 push_back이 더 효율적일 때도 있음)



'STL - Containers > vector' 카테고리의 다른 글

[C++ STL] std::vector - push_back  (0) 2016.02.19
[C++ STL] std::vector 주요 멤버 함수 목록  (0) 2015.11.23
[C++ STL] std::vector 개요  (3) 2015.11.10

※ 요약

std::vector의 멤버 함수인 push_back에 대한 내용이다. 멤버 함수 push_back은 vector의 끝에 요소를 추가할때 사용하는 함수며, 이번 포스팅에서는 C++03과 C++11에서의 사용방법에 대해 간단히 알아보도록 하겠다. 참고로 아래 내용은 vector의 특성을 알고 있다고 전제하고 진행하니 vector의 특성을 잘 모르면 이 게시물을 참고하기 바란다. 또 push_back과 같은 기능을 하지만 성능상 더 유리한 emplace_back에 대한 내용도 정리한게 있으니 꼭 읽어보기 바란다.

※ 함수 원형

void push_back( const T& value );
void push_back( T&& value );        //C++11

push_back의 함수 원형은 C++03때까지 하나였다가 C++11에 추가된 Move Semantics(R-Value) 개념 때문에 하나가 더 추가되서 2개다. 첫 번째는 기존처럼 값 복사를 통해 요소를 추가하고, 두 번째는 (임시)객체의 복사가 아닌 이동을 통해 요소를 추가하므로 불필요한 복사 과정을 없애 오버헤드를 줄였다. Move Semantics나 R-Value에 대해 더 알고 싶으면 이 게시물에 있는 "02. Rvalue Reference and constexpr.pdf"를 보기 바란다.

※ C++03 기본 자료형 예제

아래는 push_back을 이용해 요소를 추가하는 간단한 예제다.


아래 이미지를 보면 vecInt와 vecDouble, vecInt1에 각각 5와 6, 9, 13, 5.0, 6.0이 잘 추가된 것을 확인할 수 있다.


※ C++11 기본 자료형 예제

C++11에서는 initializer_list라는 클래스 템플릿이라는 걸 제공해주는데, 아래와 같이 컨테이너를 선언과 동시에 편하게 초기화할 수 있다. 또 달라진 점으로는 push_back(4)인데, 리터럴 상수인 4는 move semantics를 통해 T&& value를 인자로 받는 함수가 호출된다. 이전 버전의 C++이었다면 push_back( const T& value )가 호출 되었을 것이다.


아래와 같이 값이 잘 추가되었다.


※ 사용자 정의형 예제

아래 예제는 사용자 정의형(구조체나 클래스)에 대한 예제다. 위에 있는 예제들처럼 push_back에 대한 예제이며 기본 데이터형이 아닌 사용자 정의형 데이터를 추가한다는 것만 빼면 위의 예제들과 다를게 없으므로 따로 설명은 하지 않겠다.


아래처럼 값이 잘 들어갔다.



※ 예제

위의 예제들은 어디까지나 설명을 위해 급조한 예제들이고, 아래 소스는 실제 사용예이다. 아래 소스에 대해 간단히 설명하자면 select 쿼리를 날리고 조회된 데이터 행의 개수에 따라 vector의 메모리 공간을 reserve 함수를 통해 미리 예약하고 데이터를 push_back하는 예제이다. 멤버함수 reserve에 대해서는 나중에 알아보도록 하겠다.



'STL - Containers > vector' 카테고리의 다른 글

[C++ STL] std::vector - emplace_back  (3) 2016.04.15
[C++ STL] std::vector 주요 멤버 함수 목록  (0) 2015.11.23
[C++ STL] std::vector 개요  (3) 2015.11.10

 

※ 요약
std::vector의 주요 멤버 함수 목록이다.
오버로딩 되는 항목들에 대해서 모두 넣지 않았지만 대략적인 설명을 할 것이므로 큰 문제는 없을 것이다.
또 한 C++03과 C++11의 구분을 색으로 할 것이며, 추후에 추가되는 C++14, C++17에 대해서도 추가하도록 하겠다.
std::vector의 본격적인 사용법을 알아보기 전에 한 번 훑어보면 도움이 될 것이다.

- C++03

- C++11

 분 류

 멤버 함수

 설 명

Iterators

begin

 첫 번째 원소를 가리키는 반복자를 리턴한다.

cbegin

 첫 번째 원소를 가리키는 상수 반복자를 리턴한다.

end

 마지막 원소를 가리키는 반복자를 리턴한다.

cend

 마지막 원소를 가리키는 상수 반복자를 리턴한다.

rbegin

 역 순차열의 첫 번째 원소를 가리키는 반복자를 리턴한다.

crbegin

 역 순차열의 첫 번째 원소를 가리키는 상수 반복자를 리턴한다.

rend

 역 순차열의 마지막 원소를 가리키는 반복자를 리턴한다.

crend

 역 순차열의 마지막 원소를 가리키는 상수 반복자를 리턴한다.

Element access

at

 n번째 원소를 참조할 때 사용하며 범위 점검을 하므로 []보다 느리다.

operator[]

 n번째 원소를 참조할 때 사용하며 범위 점검을 안하므로 at보다 빠르다.

front

 첫 번째 원소의 참조를 리턴한다.

back

 마지막 원소의 참조를 리턴한다.

Capacity

empty

 원소 존재 유무를 체크한다. 아무것도 없으면 true, 있으면 false를 리턴한다.

size

 원소의 개수를 리턴한다.

max_size

 담을 수 있는 원소의 최대 개수를 리턴한다.

resize

 vector의 크기를 변경하고 default 값이나 임의 값으로 초기화한다.

capacity

 vector에 할당된 메모리의 크기를 리턴한다.

reserve

 지정한 크기 만큼의 메모리를 미리 할당한다.

shrink_to_fit

 사용되지 않는 capacity size를 제거한다. 즉 size() == capacity()가 된다.

Modifiers

clear

 vector의 모든 원소를 제거한다.

assign

 기존 원소들은 모두 제거 후, 임의 값으로 n개의 원소를 할당한다.

insert

 임의 위치에 임의 값을 삽입한다.

emplace

 원소 삽입시 컨테이너 내부에서 생성 후 임의 위치에 임의 값을 삽입한다.

emplace_hint

 제공 안 함

erase

 임의 위치의 원소나 지정 범위의 원소를 삭제한다.

push_front

 제공 안 함

emplace_front

 제공 안 함

pop_front

 제공 안 함

push_back

 vector의 끝에 원소를 추가한다.

emplace_back

 원소 삽입시 컨테이너 내부에서 생성 후 컨테이너의 끝에 원소를 추가한다.

pop_back

 vector의 마지막 원소를 제거한다.

swap

 v1.swap( v2 )일때 v1과 v2를 swap한다.

List operations

merge

 제공 안 함

splice

 제공 안 함

remove

 제공 안 함

remove_if

 제공 안 함

reverse

 제공 안 함

unique

 제공 안 함

sort

 제공 안 함

Lookup

count

 제공 안 함

find

 제공 안 함

lower_bound

 제공 안 함

upper_bound

 제공 안 함

equal_range

 제공 안 함

Observers

key_comp

 제공 안 함

value_comp

 제공 안 함

hash_function

 제공 안 함

key_eq

 제공 안 함

Allocator

get_allocator

 vector의 allocator 객체를 반환한다.




'STL - Containers > vector' 카테고리의 다른 글

[C++ STL] std::vector - emplace_back  (3) 2016.04.15
[C++ STL] std::vector - push_back  (0) 2016.02.19
[C++ STL] std::vector 개요  (3) 2015.11.10

※ std::vector 요약
필자가 std::map과 함께 가장 많이 사용하는 시퀀스 컨테이너 std::vector에 대한 설명이다.
std::vector는 동일 타입의 자료 집합으로써 흔히 배열에 비유를 많이 한다.
또한 템플릿 기반이므로 임의 타입을 요소로 가질 수 있으며, 요소 개수에 따라 동적으로 메모리를 관리한다.
다른 컨테이너들에 비해 구조가 단순하고 사용 방법이 쉬우며 속도도 빠른편이다, 또 실용적이라 활용 빈도가 높다.

※ std::vector의 특징
- 배열을 대체할 수 있다.
- 동일 타입의 자료 집합이며 각 요소는 연속된 위치에 배치된다.
- 연속된 위치에 배치되므로 임의 위치를 빠른 속도로 액세스 할 수 있다.
- 최상위 레벨의 임의 접근 반복자를 제공하므로 STL의 거의 모든 알고리즘 사용 가능하다.
- 삽입, 삭제 속도가 느리다. 중간 삽입, 삭제는 더 느리다.

※ std::vector와 배열
- 배열의 크기는 고정이지만 std::vector는 요소 개수에 따라 자동(동적)으로 늘어난다.
- 배열과 std::vector 모두 사용 방법이 쉽다.
- 배열과 std::vector 모두 데이터를 연속된 위치에 순차적으로 저장한다.
- 연속된 위치에 순차적으로 저장하므로 랜덤 엑세스가 가능하다.
- 속도는 보통 배열이 std::vector보다 빠르다.
 
※ std::vector를 사용해야 하는 경우

- 저장할 데이터의 개수가 가변적일때
- 중간에 데이터 삽입, 삭제가 적거나 없을때
- 저장된 요소를 자주 검색하지 않을때
- 랜덤 엑세스를 자주 할때


 

+ Recent posts