0

boost::hash_valueそのため、共有ライブラリからエクスポートされるクラスのオーバーライドを実装しています。hash_valueこのクラスを利用するすべての人がその機能を利用できるようにしたいと思います。現在、私のhash_value関数は、クラスのインラインメンバーを呼び出すだけですが、エクスポートされ、cppファイルで定義されています。代わりに、不要な関数呼び出しを回避するために、このhash_value関数もインライン化する必要があります。現在、ヘッダーは次のようになっています。

#ifdef MYDLL
#define MY_API __export
#else
#define MY_API __import
#endif

class MY_API MyGUID
{
public:
     ...
     inline size_t Hash() const
     {  return m1 ^ m2; }
     ...
private:
     size_t m1,m2;
};

namespace boost
{
    // Defined in .cpp file; just returns inGUID.Hash();
    MY_API size_t hash_value(const MyGUID &inGUID);
}

しかし、私はそのhash_valueをもっと次のようにしたいと思います:

   namespace boost
    {
        // I'd like to inline this, like so:
        static inline size_t hash_value(const MyGUID &inGUID)
        { 
             return inGUID.Hash();
        }
    }

上記のコードを除いて、それを含むすべての.cppファイルでhash_valueを定義し、バイナリを散らかしている可能性が高く、原則として醜いです。

関数呼び出しがパフォーマンスに測定可能な違いをもたらすかどうかという問題は別として、ordered_setなどのハッシュコンテナーでMyGUIDを使用するこの共有ライブラリのクライアントに対してクラスのハッシュ関数をインライン化するにはどうすればよいですか?

テンプレートが関係しているのではないかと思いますが、どうすればいいのかよくわかりませんでした。

4

1 に答える 1

1

内部boost/functional/hash/hash.hppを見ると、既存の型のhash_valueが次のように定義されていることがわかります。

inline std::size_t hash_value(bool v)
{
    return static_cast<std::size_t>(v);
}

ブーストがすでにテクニックを使用している場合、これはあなたが同じことをするのが安全であるというあなたのヒントです!ヘッダーファイルでの使用の非効率性に関する懸念についてinlineは、まさにそれが使用されるように設計されており、関数は単に別の関数呼び出しに転送するだけなので、コードサイズはまったく増加しません。

プリプロセッサディレクティブで非常に凝ったことをするつもりでない限り、使用することはあまり意味がありませんstatic inline。つまり、この関数の1つのバージョンが必要な場合は、それをとしてマークしinlineます。

于 2012-09-12T18:59:05.517 に答える