2012-05-07 10 views
1

私はVisual C++ 2008を使ってWindowsビルドからC++プログラムを変換して、gcc 4.6.1でLinux上にビルドしています。 <unordered_map>を使用するモジュールがあります。 VC++で、私たちが実際にそう純粋なC++ 2011のコードが実行可能ではない使用して、ちょうど4.6 gccとVC++ 2008よりも多くのコンパイラをサポートしているC++ std :: tr1 :: hash :: operator()undefined?

#include <unordered_map> 

... 



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

に完全にOKのようです。 GCCは、これが本当のブルーC++ 2011がそうファイル、私はこの仕事が

#include <tr1/unordered_map> 

... 


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

この作品に含める変更して作るためにしなければならなかったものの一つが含まれていることを訴えて、#include <unordered_map>と怒ります。けっこうだ。しかし、私は別の問題を抱えています。ここでは体mystructの定義です:VC++ 2008で

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

が、これはmystructに特化するほどstd::hashとしてニーズのようです。一方、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演算子を定義できるようにするのは非常にエレガントなようですが、私はstd::tr1::hashoperator()を定義しています。

更新:

私は、提案されているように、ハッシュクラス全体を専門化しようとしました。 GCCとの建物は、私はあなたのmystructがユーザーによって定義されているので、あなたがunordered_mapのためにハッシュ関数を提供する必要が

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>' 

答えて

6

Microsoftの道、std::size_tへの暗黙的な変換を受け入れるように、あります拡張。

std::tr1::hashを専門にするGCCの方法は、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; 
      } 
     }; 
    } 
} 
+0

まさに私が知りたいと思ったもの。ありがとうございました! –

+0

興味深いことに、私はクラス全体を専門にしてみましたが、gccはそれを好まなかったのです。上記を参照。 –

+0

@TedMiddleton上記参照? – Potatoswatter

2

を得る:

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

std::tr1::unordered_map<mystruct, int, my_hash> my_map; 
+0

。 –

関連する問題