부분적으로 함수 템플릿을 특수화하므로 사용자 정의 템플릿 클래스의 경우 함수 인 경우 std::hash
을 특수화 할 수 없습니다. 템플릿은 std
네임 스페이스에서만 전문화 할 수 있지만 과부하가 아니므로 템플릿 기반 클래스의 사용자는 std::unordered_map<MyClass<whatever>, MyOtherClass>
을 만들 수 없으므로 std::unordered_map<MyClass<whatever>, MyOtherClass, ???>
을 선택해야합니다. 그래서 functor가 해결책입니다.
namespace std
{
template<typename T>
struct hash<MyVector<T>>
{
size_t operator()(const MyVector<T>& v)
{
//return hash from here
}
};
}
표준 라이브러리의 다른 방법은 기본적으로 회원 .hash()
, 표준 해시 다른 경우 경우를 선택하는 몇 가지 SFINAE 템플릿 트릭을 사용하는 것입니다 만, 사용, 특히 대부분의 경우 (인터페이스를 갱신 할 수 없습니다 내 경험에
//somewhere in std::unordered_map
using std::hash;
size_t h = hash(key);
는 ADL이 까다 롭습니다하고 모두가 코너 케이스에 대한 기억 : 다른 대안 std::swap
같은 것
타사 코드) ADL과 (트릭)를 수행합니다. 게다가 여기에있는 펑터의 장점은 템플릿 매개 변수로 사용할 수 있다는 사실입니다. 기본값이 틀렸다고 생각하면 템플릿 (예 : std::unordered_map<A, B, specialized_hash<A>>
)에 다른 펑터를 플러그인하면됩니다.
의견에서
:
하지만 당신은 표준 : 스왑에 대해 좀 더 정교한 수 있을까? 아직 거기에있어 C++ 11에서 그리고 그것은 사용자 정의 유형에 문제가 있습니까? 왜 은 더 많은 것을 만들기보다는 STL에서 많은 개념을 유지해야 하는가? ?
std::hash
에서 :
std::swap
와 std::hash
사이에 약간의 차이가있다 std::string
클래스 작성자가 정의한 해시가 충분하지 않을 수 있습니다. 즉, 너무 일반적이어서 해시 맵에 한 종류의 문자열 만 넣을 수 있음을 보장 할 수 있으므로 해시 함수를 더 빨리 또는/충돌이 적습니다.
- 은 그것의 :들이 generic 여기에 훨씬 덜 중요하다, 그래서
- 은 가능 대부분의 경우
- 당신이 더 나은 해시
std::swap
에서
을 만들기 위해 서로 다른 목적을 위해 해시 많은 종류가 있습니다 자신의 스왑 함수를 원할 것 같지는 않지만 아마도 복사 생성자를 호출하는 generic std::swap
이 아닌이 클래스에 해당하는 특정 클래스를 사용하려고 할 것입니다.
대부분의 경우 클래스 내부에 대한 지식이 필요하므로 스왑 함수를 만들조차 할 수 없습니다 (예 : std::vector
은 포인터가 비공개 필드로 숨겨진 동적 배열로 구현 될 수 있으므로 혼자서 교환하는 것이 아니라, 그 방법으로 구현 된 사실조차도 보장되지는 않습니다.)
하나의 스왑이 존재합니다.
실제로는 std::swap
에 문제가 있습니다. 표준 컨테이너는 swap
멤버 함수를 제공하고 std::swap
은 특수화 될 수 있지만 (템플릿이없는 클래스에만 해당) 스왑은 ADL에서 찾을 수있는 무료 함수로 정의 할 수 있습니다. 스왑을 어떻게 제공해야합니까? IMO는 혼란 스럽지만 실제로는 std::swap
이 기능하고 std::hash
은 functor입니다.
왜 STL이 일치하지 않습니까? 여기서만 추측 할 수 있지만 STL이 일치하지 않는 주된 이유는 (a) bawkward 호환성이며 (b) C++ 또한 매우 일관성이 없습니다.
@RiaD 감사합니다. 갑자기, 그것은 더 어색함을 느낀다. –