2012-08-30 3 views
3

C++ 템플리트 메타 기능을 사용하여 컴파일 할 때 모든 계산이 가능합니다. 다음이 가능했던 경우에 따라서, 나는 생각했다 :해시 템플리트 메타 기능 및 기능

void my_function(char const* string_ptr) 
{ 
    switch (hash_function(string_ptr)) 
    { 
    case hash_metafunction<"yoohooo">::value: 
     ... 
     break; 

    case hash_metafunction<"woooooo">::value: 
     ... 
     break; 

    ... 
    } 
} 

당신은 해시 기능과 템플릿 metafunction 모두 코드 (라이브러리)을 찾을 수있는 곳으로 리드를 제공 할 수 있습니다. 그러한 라이브러리가 없으면 템플릿 메타 기능을 롤백하는 방법에 대한 힌트를 줄 수 있습니까? 특히 템플릿 메타 함수에 대한 char const* 매개 변수가 걱정됩니다. 어쩌면 일부 전처리 부 마법이 가능할까요?

+3

문자열 리터럴은 템플릿 매개 변수가 될 수 없습니다. 그러나 사용자 정의 리터럴이 필요할 수도 있습니다 :''yoohooo "_hash'. –

+0

이것이 전 처리기 마법, 즉 가변성 템플릿 'y', 'o', 'o', 'h'...를 사용하는 것이 가능한 이유입니다. – user1095108

+0

사실, 문자열 리터럴에 대해 templaty UDL을 사용할 수 없습니다. 그러나 foo 를 쓰면 물론 할 수 있습니다. –

답변

7

constexpr 기능은 어떻습니까? 물론 해시를 구현하는 것은 어려울 수 있습니다.

// maybe another return type 
constexpr uint64_t hash_metafunction(const char* input) { 
    // replace some_value with the hash implementation 
    return some_value; 
} 

void my_function(char const* string_ptr) 
{ 
    switch (hash_function(string_ptr)) 
    { 
    case hash_metafunction("yoohooo"): 
     ... 
     break; 

    case hash_metafunction("woooooo"): 
     ... 
     break; 

    ... 
    } 
} 

hash_metafunction 기능은 컴파일 시간에 실행됩니다 : 당신이 뭔가를해야합니다.

편집는 :

constexpr uint64_t do_the_hash(const char* input, uint64_t value_so_far) { 
    return *input ? do_the_hash(input + 1, (value_so_far << 8) | *input) : value_so_far; 
} 

constexpr uint64_t hash_metafunction(const char* input) { 
    return do_the_hash(input, 0); 
} 

라이브 데모 here : 이것은 기본적으로 uint64_t에 입력 문자열을 변환하는 순진 구현입니다.

편집 : 나는 MD5, 당신은 소스 코드 here을 찾을 수있는 컴파일 시간을 구현했습니다. 그것을 사용하려면, 다음을 수행하십시오 "b8b4e2be16d2b11a5902b80f9c0fe6d6"

#include <iostream> 
#include "md5.h" 

int main() { 
    constexpr auto value = ConstexprHashes::md5("constexpr rulz"); 

    std::cout << std::hex; 
    for(auto v : value) { 
     if(((size_t)v & 0xff) < 0x10) 
      std::cout << '0'; 
     std::cout << ((size_t)v & 0xff); 
    } 
    std::cout << std::endl; 
} 

이 해시를 출력합니다.

+0

아이디어가 좋습니다. 문자열에있는 모든 문자를 반복하는 방법은 무엇입니까? – user1095108

+0

저기, 제 대답을 편집했습니다. 모든 것은 재귀 적으로 수행됩니다. – mfontanini

+0

놀랍지 만 비슷한 기능을 가진 라이브러리가 존재하지 않습니다. – user1095108

1

MurmurHash3constexpr 버전을 gist on GitHub으로 만들었습니다.

int main() { 
    constexpr uint32_t hash = Murmur3_32("some_string_to_hash", 0xAED123FD); 
    assert(hash == 4291478129); 
}