일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 영화
- 티스토리챌린지
- Smart Pointer
- 예외
- 반복자
- 참조자
- 다형성
- reference
- c++
- Vector
- 루아
- exception
- 영화 리뷰
- 언리얼
- 메타테이블
- implicit conversion
- 오블완
- virtual function
- operator new
- 비교 함수 객체
- UE4
- lua
- effective stl
- 스마트 포인터
- 상속
- 게임
- resource management class
- 암시적 변환
- Effective c++
- more effective c++
Archives
- Today
- Total
스토리텔링 개발자
[Effective STL] 19. 상등(equality)과 동등(equivalence) 관계 본문
728x90
항목 19. 상등 관계(equality)와 동등 관계(equivalence)의 차이를 파악하자
STL 비교 동작
- STL의 대부분의 동작은 객체들 사이의 비교 동작이다.
- find(), insert()
- 이 두 함수는 '두 값이 같은가?'를 알아내는 대표적인 함수이지만, 동작 방식이 상이하다.
- find
- 상등성(equality)
- operator==를 사용한다.
- insert
- 동등성(equivalence)
- operator<를 사용한다.
- find
상등성(equality)
- 어떤 표현식 "x == y"가 참이라고 하면 x, y는 같으며, 거짓이면 다르다.
- 하지만, x, y가 같다고 해서 x, y의 모든 데이터 멤버가 같은 값이라는 뜻은 아니다.
class Widget
{
public:
...
private:
TimeStamp lastAccessed;
...
};
bool operator==(const Widget& lhs, const Widget& rhs)
{
// 같은지의 여부를 알아볼 때 lastAccessed 필드를 고려하지 않음
// 상등성 체크(operator==)로는 lastAccessed가 달라도 같은 것으로 체크된다.
}
동등성( equivalence)
- 정렬된 범위 안에 있는 객체 값들의 상대적인 순서에 따른다.
- 모든 연관 컨테이너(set, multiset, map, multimap)가 내부 데이터 요소를 관리할 때 사용하는 정렬 순서
- 컨테이너 c의 어떤 객체 x, y에 대해
- x, y 모두가 c의 정렬 순서에 대해 서로의 앞에 오지 않으면 x, y는 동등하다.
set<Widget> s;
// s의 멤버 w1, w2에 대해
!(w1 < w2) && !(w2 < w1)
// 위의 식을 만족하면 w1, w2는 동등하다.
// 하지만, 일반적으로 연관 컨테이너 비교 함수는 operator<가 아니라 less이다.
// less는 사용자 정의가 가능한 술어 구조(predicate)이다.(항목 39 참조)
// 그러므로 아래 수식이 좀 더 정확하다.
!c.key_comp()(w1, w2) && !c.key_comp()(w2, w1)
상등성과 동등성 예제
- 임의의 set<string>이 있고, 이 셋은 대소문자를 구분하지 않는다.
/* struct CIStringCompare
{
public:
binary_function<string, string, bool>
{
bool operator()(const string& lhs, const string& rhs) const
{
return ciStringComapre(lhs, rhs);
}
}
} */
// binary_function은 c++17에서 제거되었으므로
// 아래처럼 구현해야 한다.
struct CIStringCompare
{
public:
bool operator()(const string &lhs, const string &rhs) const
{
return ciStringCompare(lhs, rhs);
}
};
set<string, CIStringCompare> ciss;
ciss.insert("Persephone"); // 새 요소 추가
ciss.insert("persephone"); // 동등한 것이 있으므로 추가되지 않는다.
// 이 조건문은 참이다.(동등성)
if(ciss.find("persephone") != ciss.end()) ...
// 이 조건문은 거짓이다.(상등성)
if(find(ciss.begin(), ciss.end(), "persephone") != ciss.end()) ...
표준 연관 컨테이너가 상등성이 아닌 동등성에 기반을 둔 이유
- 표준 연관 컨테이너의 요소는 정렬된 순서로 관리되므로, 비교함수가 반드시 필요하다.
- 기본적으로는 less를 사용한다.
- 만일 표준 연관 컨테이너가 상등성을 지원해야 했다면,
- 정렬용 비교 함수 외에도 상등성을 알아내는 함수가 하나 더 필요했을 것이다.
- 그렇다면 비교 함수와 상등성을 지원하는 컨테이너가 있다고 가정해 보자.
set2CF<string, CIStringCompare/*동등비교함수*/, equal_to<string>/*상등비교함수*/> s;
// 이렇게 insert 하면 어떻게 될까?
s.insert("Persephone");
s.insert("persephone");
// 두번째 insert는 동등성에 따라 추가되지 않아야 할까?
// 상등성에 따라 추가되어야 할까?
// 마찬가지로, 아래 find는 성공일까 실패일까?
if(s.find("persephone") != s.end()) ...
// find 자체는 상등성 검사를 할 테지만..
// 위의 insert에서 persephone이 insert 되었는지 안되었는지가 결국 중요해진다.
참고
- 표준 연관 컨테이너가 정렬된 요소를 가지지 않는 경우에는 상등성과 동등성을 모두 사용한다.
- hash_set 등(항목 25 참조)
728x90
'개발 > Effective STL' 카테고리의 다른 글
[Effective STL] 21. 연관 컨테이너 비교 함수 객체의 동일값 비교 (0) | 2024.12.04 |
---|---|
[Effective STL] 20. 컨테이너 비교 함수 객체 (0) | 2024.12.03 |
[Effective STL] 18. vector<bool> 주의 (0) | 2024.11.27 |
[Effective STL] 17. swap 트릭으로 vector 용량 줄이기 (0) | 2024.11.26 |
[Effective STL] 16. C API로 컨테이너 전달 (0) | 2024.11.25 |
Comments