Namespaces
Variants

std:: hash

From cppreference.net
Utilities library
헤더에 정의됨 <bitset>
헤더에 정의됨 <coroutine>
(C++20부터)
헤더에 정의됨 <chrono>
(C++26부터)
헤더에 정의됨 <filesystem>
(C++17부터)
헤더에 정의됨 <functional>
헤더에 정의됨 <memory>
헤더에 정의됨 <optional>
(C++17부터)
헤더에 정의됨 <stacktrace>
(C++23부터)
헤더에 정의됨 <string>
헤더에 정의됨 <string_view>
(C++17부터)
헤더에 정의됨 <system_error>
헤더에 정의됨 <text_encoding>
(C++26부터)
헤더에 정의됨 <thread>
헤더에 정의됨 <typeindex>
헤더에 정의됨 <utility>
(C++26부터)
헤더에 정의됨 <variant>
(C++17부터)
헤더에 정의됨 <vector>
template < class Key >
struct hash ;
(C++11부터)

hash 템플릿의 활성화된 특수화들은 해시 함수 를 구현하는 함수 객체를 정의합니다.

주어진 타입 Key 에 대해, 각 전문화 std::hash<Key> 활성화 되거나 비활성화 됩니다:

  • 만약 std::hash<Key> 가 프로그램이나 사용자에 의해 제공되지 않으면, 비활성화됩니다.
  • 그렇지 않으면, std::hash<Key> 는 다음의 모든 조건이 충족될 때 활성화됩니다:
  • 다음 모든 요구사항을 만족합니다:
  • 다음 값들이 주어졌을 때:
  • h , std::hash<Key> 타입의 객체
  • k1 k2 , Key 타입의 객체들
다음 모든 요구사항을 만족합니다:
  • 만약 k1 == k2 true 라면, h ( k1 ) == h ( k2 ) 또한 true 입니다.
  • std::hash<Key> 프로그램 정의 특수화 가 아닌 한, h ( k1 ) 는 예외를 발생시키지 않습니다.
  • 그렇지 않으면, std::hash<Key> 는 비활성화됩니다.

비활성화된 특수화는 Hash 요구 사항을 충족하지 않으며, FunctionObject 요구 사항도 충족하지 않습니다. 그리고 다음 값들은 모두 false 입니다:

**참고:** 제공된 HTML 내용은 이미 C++ 코드와 관련된 내용으로, 번역이 필요한 일반 텍스트가 포함되어 있지 않습니다. 모든 내용이 HTML 태그, C++ 코드, 또는 C++ 관련 용어로 구성되어 있어, 지시사항에 따라 번역하지 않고 원본을 그대로 유지했습니다.

다시 말해, 그들은 존재하지만 사용할 수 없습니다.

목차

중첩 타입

타입 정의
argument_type (C++17에서 사용 중단됨) Key
result_type (C++17에서 사용 중단됨) std::size_t
(C++20 이전)

멤버 함수

해시 함수 객체를 생성합니다
(public member function)
인자의 해시 값을 계산합니다
(public member function)

표준 라이브러리 특수화

다음 타입들에 대해 활성화된 std::hash 특수화를 제공하는 각 헤더는 std::hash 템플릿을 선언합니다:

독립형 구현 은 앞서 언급된 특수화들과 기본적으로 비활성화된 특수화들을 제공해야 합니다.

(C++20부터)

게다가, 일부 헤더는 라이브러리 타입에 대해 다른 활성화된 std::hash 특수화도 제공합니다 (자세한 내용은 아래 참조).

표준 라이브러리가 제공하는 모든 std::hash 특수화에 대해, 다음을 제외한 모든 멤버 함수는 noexcept 입니다:

(C++26부터)
(C++17부터)

라이브러리 타입에 대한 특수화

언어 지원 라이브러리
std::coroutine_handle 에 대한 해시 지원
(클래스 템플릿 특수화)
진단 라이브러리
std::error_code 에 대한 해시 지원
(클래스 템플릿 특수화)
std::error_condition 에 대한 해시 지원
(클래스 템플릿 특수화)
std::type_index 에 대한 해시 지원
(클래스 템플릿 특수화)
std::stacktrace_entry 에 대한 해시 지원
(클래스 템플릿 특수화)
std::basic_stacktrace 에 대한 해시 지원
(클래스 템플릿 특수화)
메모리 관리 라이브러리
std::unique_ptr 에 대한 해시 지원
(클래스 템플릿 특수화)
std::shared_ptr 에 대한 해시 지원
(클래스 템플릿 특수화)
std::indirect 에 대한 해시 지원
(클래스 템플릿 특수화)
범용 유틸리티 라이브러리
std::optional 에 대한 해시 지원
(클래스 템플릿 특수화)
std::variant 에 대한 해시 지원
(클래스 템플릿 특수화)
std::monostate 에 대한 해시 지원
(클래스 템플릿 특수화)
std::bitset 에 대한 해시 지원
(클래스 템플릿 특수화)
컨테이너 라이브러리
std::vector<bool> 에 대한 해시 지원
(클래스 템플릿 특수화)
문자열 라이브러리
문자열을 위한 해시 지원
(클래스 템플릿 특수화)
문자열 뷰에 대한 해시 지원
(클래스 템플릿 특수화)
텍스트 처리 라이브러리
std::text_encoding 에 대한 해시 지원
(클래스 템플릿 특수화)
시간 라이브러리
std::chrono::duration 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::time_point 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::day 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::month 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::year 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::weekday 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::weekday_indexed 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::weekday_last 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::month_day 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::month_day_last 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::month_weekday 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::month_weekday_last 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::year_month 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::year_month_day 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::year_month_day_last 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::year_month_weekday 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::year_month_weekday_last 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::zoned_time 에 대한 해시 지원
(클래스 템플릿 특수화)
std::chrono::leap_second 에 대한 해시 지원
(클래스 템플릿 특수화)
입출력 라이브러리
std::filesystem::path 에 대한 해시 지원
(클래스 템플릿 특수화)
동시성 지원 라이브러리
std::thread::id 에 대한 해시 지원
(클래스 템플릿 특수화)

참고 사항

실제 해시 함수는 구현에 따라 다르며 위에서 명시된 기준 외에는 다른 품질 기준을 충족할 의무가 없습니다. 특히 일부 구현에서는 정수를 자기 자신으로 매핑하는 단순한(항등) 해시 함수를 사용합니다. 다시 말해, 이러한 해시 함수는 예를 들어 암호화 해시가 아닌 비정렬 연관 컨테이너와 함께 작동하도록 설계되었습니다.

해시 함수는 프로그램의 단일 실행 내에서 동일한 입력에 대해 동일한 결과를 생성하기만 하면 됩니다. 이를 통해 충돌 기반 서비스 거부 공격을 방지하는 솔트 처리된 해시가 가능해집니다.

C 문자열에 대한 특수화는 존재하지 않습니다. std :: hash < const char * > 는 포인터 값(메모리 주소)의 해시를 생성하며, 문자 배열의 내용을 검사하지 않습니다.

추가적인 특수화들은 std::pair 및 표준 컨테이너 타입들에 대해, 그리고 해시를 구성하기 위한 유틸리티 함수들이 boost::hash 에서 사용 가능합니다.

예제

#include <cstddef>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_set>
struct S
{
    std::string first_name;
    std::string last_name;
    bool operator==(const S&) const = default; // C++20부터
};
// C++20 이전
// bool operator==(const S& lhs, const S& rhs)
// {
//     return lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name;
// }
// 커스텀 해시는 독립적인 함수 객체일 수 있습니다.
struct MyHash
{
    std::size_t operator()(const S& s) const noexcept
    {
        std::size_t h1 = std::hash<std::string>{}(s.first_name);
        std::size_t h2 = std::hash<std::string>{}(s.last_name);
        return h1 ^ (h2 << 1); // 또는 boost::hash_combine 사용
    }
};
// std::hash의 커스텀 특수화는 std 네임스페이스에 주입될 수 있습니다.
template<>
struct std::hash<S>
{
    std::size_t operator()(const S& s) const noexcept
    {
        std::size_t h1 = std::hash<std::string>{}(s.first_name);
        std::size_t h2 = std::hash<std::string>{}(s.last_name);
        return h1 ^ (h2 << 1); // 또는 boost::hash_combine 사용
    }
};
int main()
{
    std::string str = "Meet the new boss...";
    std::size_t str_hash = std::hash<std::string>{}(str);
    std::cout << "hash(" << std::quoted(str) << ") =\t" << str_hash << '\n';
    S obj = {"Hubert", "Farnsworth"};
    // 독립적인 함수 객체 사용
    std::cout << "hash(" << std::quoted(obj.first_name) << ", "
              << std::quoted(obj.last_name) << ") =\t"
              << MyHash{}(obj) << " (MyHash 사용) 또는\n\t\t\t\t"
              << std::hash<S>{}(obj) << " (주입된 특수화 사용)\n";
    // 커스텀 해시를 사용하면 커스텀 타입을 비정렬 컨테이너에서 사용할 수 있습니다.
    // 이 예제는 위에서 주입된 std::hash<S> 특수화를 사용하며,
    // MyHash를 대신 사용하려면 두 번째 템플릿 인자로 전달하십시오.
    std::unordered_set<S> names = {obj, {"Bender", "Rodriguez"}, {"Turanga", "Leela"}};
    for (auto const& s: names)
        std::cout << std::quoted(s.first_name) << ' '
                  << std::quoted(s.last_name) << '\n';
}

가능한 출력:

hash("Meet the new boss...") =  10656026664466977650
hash("Hubert", "Farnsworth") =  12922914235676820612 (using MyHash) 또는
                                12922914235676820612 (using injected specialization)
"Bender" "Rodriguez"
"Turanga" "Leela"
"Hubert" "Farnsworth"

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 2119 C++11 확장 정수형에 대한 특수화가 누락됨 제공됨
LWG 2148 C++11 열거형에 대한 특수화가 누락됨 제공됨
LWG 2543 C++11 std::hash 가 SFINAE-friendly 하지 않을 수 있음 SFINAE-friendly 하게 변경됨
LWG 2817 C++11 std::nullptr_t 에 대한 특수화가 누락됨 제공됨