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;

    ...
  }
}

ハッシュ関数とテンプレートメタ関数の両方のコード(ライブラリ)を見つけるための手がかりを教えてください。そのようなライブラリが存在しない場合、テンプレートメタ関数を自分でロールする方法についてのヒントを教えてください。char const*テンプレートメタ関数のパラメータが特に気になります。たぶん、いくつかのプリプロセッサの魔法が可能ですか?

4

2 に答える 2

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関数はコンパイル時に実行されます。

編集:これは単純な実装であり、基本的に入力文字列をuint64_t:に変換します。

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);
}

ここでライブデモ。

編集:コンパイル時のMD5を実装しました。ここで、ソースコードを見つけることができます。これを使用するには、次のようにします。

#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;
}

これにより、ハッシュ「b8b4e2be16d2b11a5902b80f9c0fe6d6」が出力されます。

于 2012-08-30T14:43:40.510 に答える
1

GitHubで要点としてのconstexprバージョンを作成しました。MurmurHash3

int main() {
  constexpr uint32_t hash = Murmur3_32("some_string_to_hash", 0xAED123FD);
  assert(hash == 4291478129);
}
于 2013-07-17T16:52:28.040 に答える