2

現在、プロジェクトでBoostのハッシュマップの実装を使用しており、キーのカスタムタイプを実装しようとしています。キーとして使用する単一の128ビットデータ型に結合したい4つの符号なし整数があります。

4つの要素の32ビット整数配列を使用して構造体を作成しました。これはストレージとして機能します。正直なところ、Boostのハッシュマップがどのように機能するかわからないので、ここで何をしているのかわかりませんが、Boostのドキュメント(http://www.boost.org/doc/libs/1_37_0 )に従いました。 /doc/html/hash/custom.html)boost :: hashを拡張するために、ハッシュ関数とカスタム比較演算子を作成しました。

このカスタムタイプをヘッダーで定義しています。これは私のコードです:

#ifndef INT128_H_
#define INT128_H_

// Custom 128-bit datatype used to store and compare the results of a weakened hash operation.
struct int128
{
    unsigned int storage[4];

    /* Assignment operation that takes a 32-bit integer array of four elements.
    This makes assignment of values a shorter and less painful operation. */
    void operator=(const unsigned int input[4])
    {
        for(int i = 0; i < 4; i++)
            storage[i] = input[i];
    }
};

bool operator==(int128 const &o1, int128 const &o2)
{
    if(o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
       o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3])
        return true;

    return false;
}

// Hash function to make int128 work with boost::hash.
std::size_t hash_value(int128 const &input)
{
    boost::hash<unsigned long long> hasher;
    unsigned long long hashVal = input.storage[0];

    for(int i = 1; i < 3; i++)
    {
        hashVal *= 37;
        hashVal += input.storage[1];
    }

    return hasher(hashVal);
}

#endif

Boostの順序付けされていないマップで実際にこのタイプを使用すると、コードはコンパイルされますが、リンクに失敗します。リンカは、いくつかのオブジェクトファイルでシンボルが複数回定義されていると主張しています。128ビットタイプをこのマップで動作させたいのですが。私が台無しにしていることに関するヒント、またはこれを行うためのより良い方法はありますか?

4

2 に答える 2

3

順序付けられていないマップの関与は、発生している問題にほぼ付随しています。本当の問題は、上記のヘッダーを含むすべてのファイルで定義hash_valueしていることです。operator==

これは次のいずれかで解決できます。

  1. 両方をインライン関数として定義する
  2. ヘッダーでそれらを宣言するだけです

後者を行う場合(そしてそれが通常必要なことです)、それらの関数の定義を.cppファイル(またはC ++ソースファイルに使用する拡張子)に移動します。次に、そのファイルをコンパイルし、結果のオブジェクトをint128タイプを使用する他のコードにリンクします。

編集:次のように、比較をよりクリーンにすることができます。

bool operator==(int128 const &o1, int128 const &o2)
{
    return o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
           o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3]);
}
于 2009-12-01T23:32:10.763 に答える
1

リンカは、いくつかのオブジェクトファイルでシンボルが複数回定義されていると主張しています。

関数を次のように宣言しますinline

于 2009-12-02T00:11:02.573 に答える