C++ブshared_ptrとしてhash_mapキー
-
23-08-2019 - |
質問
を作ってニューラルネットワークを使いたいという、hash_mapく重量参考のための出力ニューロンの各ニューロン:
class Neuron; //forward declaration was there (sorry I forgot to show it earlier)
typedef double WEIGHT;
typedef stdext::hash_map<boost::shared_ptr<Neuron>,WEIGHT> NeuronWeightMap;
class Neuron
{
private:
NeuronWeightMap m_outputs;
//...
public:
Neuron();
~Neuron();
//...
WEIGHT GetWeight(const boost::shared_ptr<Neuron>& neuron) const
{
NeuronWeightMap::const_iterator itr = m_outputs.find(neuron);
if( itr != m_outputs.end() )
{
return itr->second;
}
return 0.0f;
}
};
こを利用できませんのブ::shared_ptrとしてのstdext::hash_mapどのように提案?あるワーク-aroundsのみを使用するオプションと異なるキーでもスイッチは、std::地図か?よろしく!
ここではエラー:
1>c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(61) : error C2440: 'type cast' : cannot convert from 'const boost::shared_ptr<T>' to 'size_t'
1> with
1> [
1> T=Neuron
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(99) : see reference to function template instantiation 'size_t stdext::hash_value<_Kty>(const _Kty &)' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(98) : while compiling class template member function 'size_t stdext::hash_compare<_Kty,_Pr>::operator ()(const _Kty &) const'
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Pr=std::less<boost::shared_ptr<Neuron>>
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\hash_map(80) : see reference to class template instantiation 'stdext::hash_compare<_Kty,_Pr>' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Pr=std::less<boost::shared_ptr<Neuron>>
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(119) : see reference to class template instantiation 'stdext::_Hmap_traits<_Kty,_Ty,_Tr,_Alloc,_Mfl>' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Ty=common_ns::WEIGHT,
1> _Tr=stdext::hash_compare<boost::shared_ptr<Neuron>,std::less<boost::shared_ptr<Neuron>>>,
1> _Alloc=std::allocator<std::pair<const boost::shared_ptr<Neuron>,common_ns::WEIGHT>>,
1> _Mfl=false
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\hash_map(90) : see reference to class template instantiation 'stdext::_Hash<_Traits>' being compiled
1> with
1> [
1> _Traits=stdext::_Hmap_traits<boost::shared_ptr<Neuron>,common_ns::WEIGHT,stdext::hash_compare<boost::shared_ptr<Neuron>,std::less<boost::shared_ptr<Neuron>>>,std::allocator<std::pair<const boost::shared_ptr<Neuron>,common_ns::WEIGHT>>,false>
1> ]
1> FILE_PATH_REMOVED\neuralnet.h(21) : see reference to class template instantiation 'stdext::hash_map<_Kty,_Ty>' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Ty=common_ns::WEIGHT
1> ]
1>NeuralNet.cpp
1>c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(61) : error C2440: 'type cast' : cannot convert from 'const boost::shared_ptr<T>' to 'size_t'
1> with
1> [
1> T=Neuron
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(99) : see reference to function template instantiation 'size_t stdext::hash_value<_Kty>(const _Kty &)' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(98) : while compiling class template member function 'size_t stdext::hash_compare<_Kty,_Pr>::operator ()(const _Kty &) const'
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Pr=std::less<boost::shared_ptr<Neuron>>
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\hash_map(80) : see reference to class template instantiation 'stdext::hash_compare<_Kty,_Pr>' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Pr=std::less<boost::shared_ptr<Neuron>>
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\xhash(119) : see reference to class template instantiation 'stdext::_Hmap_traits<_Kty,_Ty,_Tr,_Alloc,_Mfl>' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Ty=common_ns::WEIGHT,
1> _Tr=stdext::hash_compare<boost::shared_ptr<Neuron>,std::less<boost::shared_ptr<Neuron>>>,
1> _Alloc=std::allocator<std::pair<const boost::shared_ptr<Neuron>,common_ns::WEIGHT>>,
1> _Mfl=false
1> ]
1> c:\program files (x86)\microsoft visual studio 8\vc\include\hash_map(90) : see reference to class template instantiation 'stdext::_Hash<_Traits>' being compiled
1> with
1> [
1> _Traits=stdext::_Hmap_traits<boost::shared_ptr<Neuron>,common_ns::WEIGHT,stdext::hash_compare<boost::shared_ptr<Neuron>,std::less<boost::shared_ptr<Neuron>>>,std::allocator<std::pair<const boost::shared_ptr<Neuron>,common_ns::WEIGHT>>,false>
1> ]
1> FILE_PATH_REMOVED\neuralnet.h(21) : see reference to class template instantiation 'stdext::hash_map<_Kty,_Ty>' being compiled
1> with
1> [
1> _Kty=boost::shared_ptr<Neuron>,
1> _Ty=common_ns::WEIGHT
1> ]
1>Generating Code...
解決
あなたはおそらくNeuron
はあなたの.hファイルで宣言されています。
そこで、以下では仕事ができるます:
struct hasher {
size_t operator()(const boost::shared_ptr<Neuron>& n) { return (size_t)n.get(); }
};
typedef stdext::hash_map<boost::shared_ptr<Neuron>,WEIGHT,hasher> NeuronWeightMap;
問題はおそらく、あなただけのものを提供する必要があるのでboost:shared_ptr
は、デフォルトのハッシュ関数を(1がどのように見えるか?)持っていないということです。
他のヒント
また、ハッシュのためのテンプレートの特殊化を提供することができます:
#include <functional>
#include <boost/shared_ptr.hpp>
template<class T>
class std::tr1::hash<boost::shared_ptr<T>> {
public:
size_t operator()(const boost::shared_ptr<T>& key) const {
return (size_t)key.get();
}
};
unordered_setで完璧に動作します:
class Foo;
typedef boost::shared_ptr<Foo> FooPtr;
typedef std::tr1::unordered_set<FooPtr> FooSet;
"ノーマル" Neuron*
はhash_map
のキーとして動作するはずます:
typedef stdext::hash_map<Neuron*, WEIGHT> NeuronWeightMap;
:あなたはshared_ptr
-ニューロンを検索したい場合は、あなたは生のポインタにアクセスするためにshared_ptr
sのget()
方法を使用することができます
NeuronWeightMap weights;
boost::shared_ptr<Neuron> n;
weights.find(n.get());
て使用力は、なぜ使用しないで boost::unordered_map
のためのハッシュテーブルは?で統のボックス shared_ptr
そのキーがおりチェックをしてくが進みました。順序付け)
コンパイルエラーが何であるかを上記のコードから?
あなたはクラスのニューロンを宣言前進しようとしたことがありますか?
class Neuron; // class Neuron must be forward declared to be used
typedef double WEIGHT;
typedef stdext::hash_map<boost::shared_ptr<Neuron>,WEIGHT> NeuronWeightMap;
class Neuron
{
private:
NeuronWeightMap m_outputs;
//...
public:
Neuron();
~Neuron();
//...
};
標準マップは、この場合にも問題ないはずです、hash_mapを使用するための具体的な理由は何ですか?
私はstdextの重要:: hash_mapとしてのshared_ptrを使用することができますHASH_VALUE()関数を追加することによって見つけます。 私はブースト:: STDとunordered_mapを使用して比較し、以下の:: hash_map
#include <boost/smart_ptr.hpp>
#include <boost/unordered_map.hpp>
#include <hash_map>
#include <assert.h>
struct MyItem
{
int i;
};
typedef boost::shared_ptr<const MyItem> MyItem_csptr;
struct MyExtra
{
double d;
};
//Boost's unordered_map already knows how to hash shared_ptr
typedef boost::unordered_map<MyItem_csptr,MyExtra> MapMyItemToExtra;
//But for stdext::hash_map, we need to write this:
template<class T>
size_t hash_value(const boost::shared_ptr<T>& aSptr)
{
return reinterpret_cast<size_t>( aSptr.get() );
};
typedef stdext::hash_map<MyItem_csptr,MyExtra> MapMyItemToExtra2;
template<class MAP>
void TryMapMyItemToExtra_T()
{
MAP tMap;
MyItem_csptr tItem1(new MyItem);
MyItem_csptr tItem2(new MyItem);
tMap[tItem1].d=1.0;
tMap[tItem1].d=1.1;
tMap[tItem2].d=2.0;
assert( tMap[tItem1].d == 1.1 );
assert( tMap[tItem2].d == 2.0 );
}
void TryMapMyItemToExtra()
{
TryMapMyItemToExtra_T<MapMyItemToExtra>();
TryMapMyItemToExtra_T<MapMyItemToExtra2>();
}
のハッシュ関数の問題が同様にstdext::hash_set
ために生じます。 hash_value()
を宣言してソリューションを使用すると、メインのヘッダファイルに一度だけ、それを宣言することができますので、最高です。