2.1 유용한 함수들
2.1.1 std::min, std::max, std::minmax
#include <algorithm>
std::min(a, b); //a와 b 중에서 최솟값 반환
std::min(a, b, comp); //predicate comp를 이용해 a와 b 중에서 최솟값 반환
std::min(initializer_list); //initializer list에 있는 값 중에서 최소값 반환
std::min(initializer_list, comp); //predicate comp를 이용해 initializer list 중 최소값 반환
std::max(a, b); //a와 b 중에서 최댓값 반환
std::max(a, b, comp); //predicate comp를 이용해 a와 b 중에서 최댓값 반환
std::max(initializer_list); //initializer list에 있는 값 중에서 최댓값 반환
std::max(initializer_list, comp); //predicate comp를 이용해 initializer list 중 최댓값 반환
//pair 형식으로 저장
std::minmax(a, b); //a와 b 중에서 최솟값과 최댓값 반환
std::minmax(a, b, comp); //predicate comp를 이용해 a와 b 중에서 최솟값과 최댓값 반환
std::minmax(initializer_list); //initializer list에 있는 값 중에서 최솟값과 최댓값 반환
std::minmax(initializer_list, comp); //predicate comp를 이용해 initializer list 중 최솟값과 최댓값 반환
2.1.1 std::move
- Move Semantics
- 과거 C++에서는 우측값 참조자(RValue Reference) 개념이 없었음
- 복사 생성자, 복사 연산자라는 문법만 존재하였기 때문에 임시로 필요한 객체도 복사를 통해 생성을 해야만 했음
- 우측값 참조자를 통해 임시 객체(새로운 오브젝트)들이 값을 기존 값을(소스 오브젝트) 복사하는 낭비 대신 이동(C++11 이후 지원)
- 즉 원본의 포인터를 삭제시키고 해당 포인터가 가리키는 위치로 현재 값 바꿈
#include <iostream>
#include <utility>
#include <vector>
std::vector<int> myBigVec(1000000, 2011);
/* Copy Semantics */
std::vector<int> myVec1 = myBigVec;
/* Move Semantics */
//기존 RValue Reference 사용법
std::vector<int> myVec2 = static_cast<std::remove_reference<decltype(myBigVec)>::type&&>(myBigVec);
//std::move()
std::vector<int> myVec3 = std::move(myBigVec);
std::forward
- 주어진 인수를 그대로 전달하는 함수 템플릿을 작성할 수 있음
- factory function(오브젝트를 생성하는 함수 : 주어진 인수 그대로 전달)이나 constructor를 만드는 데 주로 활용
- 즉 해당 함수는 generic library를 제작하는데 적합
#include <utility>
struct MyData{
MyData(){};
MyData(int, double, char){};
};
//가변인수 템플릿 + forwarding
template <typename T, typename ... Args> T createT(Args&&...args){
return T(std::forward<Args>(args)...);
}
int main(void){
int a = createT<int>();
int b = creatT<int>(1);
std::string s = createT<std::string>("Only for testing purpose");
MyData myData = createT<MyData>();
MyData myData2 = createT<MyData>(1, 3.19, 'a');
typedef std::vector<int> IntVec;
intVec intVec = createT<IntVec>(std::initializer_list<int>({1, 2, 3, 4, 5}));
}
std::swap
- 두 오브젝트를 맞바꾸는 작업을 쉽게 수행 가능(내부적으로 std::move 사용)
#include <utility>
template <typename T>
void swap(T& a, T& b){
T tmp(std::move(a)); //move를 활용한 swap
a = std::move(b);
b = std::move(tmp);
}