On this page
article
C++ Is transparent
std::less
의 개선 (C++14)
문제
- 기존
std::less<T>
는 타입이 같아야만 비교 가능.
개선
std::less<void>
특수화를 통해 타입이 달라도 비교 가능.
template<>
struct less<void> {
template<typename T1, typename T2>
constexpr auto operator()(T1&& a, T2&& b) const
-> decltype(std::forward<T1>(a) < std::forward<T2>(b)) {
return std::forward<T1>(a) < std::forward<T2>(b);
}
};
Transparent Function (투명 함수)
- 서로 다른 타입끼리 비교 가능하게 검색할 때 key 타입이 정확히 일치하지 않아도, 비교 가능하기만 하면 허용할 수 있게 해주는 메커니즘
- comparator (비교 함수 객체)에
is_transparent
를 추가해 타입 변환 지원. - SFINAE 기술
예시: set
에서 int
로 People
검색
struct People {
int id;
};
struct PeopleCompare {
using is_transparent = int;
bool operator()(const People& p1, const People& p2) const { return p1.id < p2.id; }
bool operator()(const People& p, int id) const { return p.id < id; }
bool operator()(int id, const People& p) const { return id < p.id; }
};
적용 예시
컨테이너 | comparator 기본값 | 투명 여부
std::set
Static operator()
(C++23)
C++23부터 operator()가 static 멤버함수가 될 수 있음
장점
- 성능
- 객체에 대한 정보를 전달할 필요가 없음(thiscall)
- 어셈블리 레벨에서 보면 그냥 멤버함수는 인자가 3개이지만 static은 2개
- 유연성
- static 함수로 만들고 변환 연산자를 제공하면 함수 포인터로 함수 객체 가리킬 수 있음
- 변환 연산자
- 함수 포인터로 함수 객체의 이름 받을 수 있게 해주는
- 성능
예시
struct Plus {
static int operator()(int a, int b) { return a + b; }
using PF = int(*)(int, int);
operator PF() const { return &Plus::operator(); }
};
- 결론
- 상태를 가지지않는 함수 객체는 static operator()를 사용하는 것이 좋음