1

Visual C++ 2008 を使用した Windows ビルドから gcc 4.6.1 を使用した Linux でビルドする C++ プログラムを変換しています。を使用するモジュールがあります<unordered_map>。VC++ では、完全に問題ないようです。

#include <unordered_map>

...



std::tr1::unordered_map<mystruct, int> my_map;

実際には、gcc 4.6 と VC++ 2008 だけでなく、より多くのコンパイラをサポートしているため、純粋な C++2011 コードを使用することは現実的ではありません。gcc は に腹を#include <unordered_map>立て、これは真の c++2011 インクルード ファイルであると不平を言います。

#include <tr1/unordered_map>

...


std::tr1::unordered_map<mystruct, int> my_map;

これは機能します。けっこうだ。しかし、今私は別の問題を抱えています。mystruct の定義は次のとおりです。

struct mystruct
{
#ifdef __cplusplus
    inline operator size_t() const
    {
        return m_val;
    }
#endif
    unsigned int m_val;
};

VC++ 2008 では、これstd::hashmystruct. std::tr1::hash一方、少なくともgcc 4.6.1では、これは好きではありません。std::tr1::hash<mystruct>::operator()( mystruct ) const未定義であると不平を言って、リンクを拒否します。適切なインクルードを行ったときに VC++ でそれが発生するかどうかはわかりませtr1ん - おそらく同じことについて文句を言うでしょうか? 明日試してみますが、今のところ、gcc を搭載した Linux ボックスしかありません。今のところ、私はそれを機能させるためにこれをしなければなりませんでした:

namespace std {
    namespace tr1 {
        std::size_t hash<mystruct>::operator()( mystruct & c ) const 
        { 
            return c.m_val; 
        }
    }
}

これがどのように機能するかについて誰かが教えてくれますか? size_tハッシュ可能にしたい型に演算子を定義できる方がはるかにエレガントに思えますが、私はoperator()onを定義して喜んで生きstd::tr1::hashます。

アップデート:

提案されているように、ハッシュクラス全体を特殊化してみました。gccでビルドすると、

myfile.cpp:41:12: error: specialization of 'std::tr1::hash<mystruct>' after instantiation
myfile.cpp:41:12: error: redefinition of 'struct std::tr1::hash<mystruct>'
/usr/include/c++/4.6/tr1/functional_hash.h:45:12: error: previous definition of 'struct std::tr1::hash<mystruct>'
4

2 に答える 2

6

への暗黙的な変換を受け入れる Microsoft の方法std::size_tは拡張です。

GCC の特殊std::tr1::hash化する方法は、TR1 によって実際に定義された方法であり、現在 C++11 で標準化されています (もちろんtr1::一部削除されています)。

MSVC は引き続きhash特殊化を受け入れる必要があり、もちろん両方とも Hasher テンプレート引数として渡されるまったく新しいクラスを受け入れる必要があります。

operator()関数だけでなく、クラス全体を特殊化する方が良いスタイルです。

namespace std {
    namespace tr1 {
        template<>
        struct hash< mystruct > {
            std::size_t operator()( mystruct & c ) const 
            { 
                return c.m_val; 
            }
        };
    }
}
于 2012-05-07T06:10:53.083 に答える
2

はユーザーによって定義されるためmystruct、次のハッシュ関数を提供する必要がありますunordered_map

struct my_hash {
std::size_t operator()( mystruct & c ) const 
        { 
            return c.m_val; 
        }
};

std::tr1::unordered_map<mystruct, int, my_hash> my_map;
于 2012-05-07T06:07:55.160 に答える