[모던C++입문] 4.4 유틸리티
- 📕 Book/모던C++입문
- 2021. 7. 20.
4.4 유틸리티
튜플
- 새로운 클래스를 구현하지 않고 여러결과를 반환하기 위해 튜플(Tuple)을 사용
- 대부분의 컨테이너와는 달리, 개체의 개수를 컴파일 타임에 알고 있어야 함
void lu(const matrix& A, matrix& LU, vector& p) {...}
tuple<matrix, vector> lu(const matrix& A)
{
matrix LU(A)
vector p(n)
...
//둘다 반환값은 동일
return tuple<matrix, vector>(LU, p);
return make_tuple(LU, p); //헬퍼 함수
}
int main()
{
tuple<matrix, vector> t = lu(A);
//튜플의 값을 가져올때는 get함수를 통해 추출한다
matrix LU = get<0>(t);
vector p = get<1>(t);
//모두 추론 가능하기에 위와 동일
auto t = lu(A);
auto LU = get<0>(t);
auto p = get<1>(t);
//튜플의 갯수보다 인덱스가크면 컴파일 오류 발생
auto stupid = get<2>(t);
//C++14에서는 항목의 타입이 명확할경우 타입별로 접근도 가능
auto t = lu(A);
auto LU = get<matrix>(t);
auto p = get<vector>(t);
//tie함수를 사용하여 튜플의 항목을 분리 가능
matrix LU;
vector p;
tie(LU, p) = lu(A);
}
function
<functional>
헤더에 있는 클래스 템플릿function
은 일반화된 함수포인터 이다.
double add(double x, double y)
{
return x + y;
}
int main()
{
using big_fun = function<double(double, double)>;
big_fun f = &add;
cout << "f(6, 3) = " << f(6,3) << endl;
}
//호환 가능함 함수 개체의 컨테이너를 만들수 있음
vector<big_fun> functions;
functions.push_back(&add); //함수는 함수포인터로 붕괴되기에 & 연산자 생략가능
//펑터도 저장 가능
struct mult
{
double operator()(double x, double y) const { return x * y; }
};
functions.push_back(mult{});
//하지만 클래스 템플릿은 타입이 아니기에 불가
template<typename Value>
struct power
{
Value operator(Value x, Value y) const { return pow(x,y); }
};
functions.push_back(power()); //오류
functions.push_back(power<double>{}); //인스턴스화된 템플릿은 가능
//함수 템플릿은 개체를 만들수 있음
struct greater_t
{
template<typename Value>
Value operator()(Value x, Value y) const { return x > y; }
} greater_than;
functions.push_back(greater_than);
function<double(float, double)> ff = greater_than; //인수타입이 달라 오류
//람다를 function 개체로 저장 가능
functions.push_back([](double x, double y) { return x / y; });
//컨테이너의 각 항목은 함수처럼 호출 가능
for( auto& f : functions)
cout << "f(6.3) = " << f(6.3) << endl;
레퍼런스 래퍼
- 일반적으로 레퍼런스의 컨테이너를 만들 수 없다
- C++11에서 reference_wrapper를 제공
vector<vector<int>&> vv; //오류
vector<reference_wrapper<vector<int>>> vv;
vector<int> v1 = {2,3,4}, v2 = {5,6,}, v3 = {7, 8};
//reference_wrapper<T> 로 암시적 변환
vv.push_back(v1);
vv.push_back(v2);
vv.push_back(v3);
vv.push_back(v2);
vv.push_back(v1);
//get 메서드로 레퍼런스를 가져와 사용할 수 있다.
for( const auto& vf : vv)
{
copy(begin(vr.get()), end(vr.get()), ostream_iterator<int>(cout, ", "));
cout << endl;
}
반응형