سؤال

أنا صنع شبكة عصبية وأراد استخدام 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، فماذا سيكون اقتراحا آخر؟ هل هناك أي عمل أو هو الخيار الوحيد لاستخدام مفتاح مختلف أو ربما التبديل إلى الخريطة STD :: MAP؟ شكرا!

هنا هي الأخطاء:

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 لا يوجد لديه وظيفة التجزئة الافتراضية (أي واحد سيبدو؟)، لذلك تحتاج فقط إلى توفير واحد.

نصائح أخرى

يمكنك أيضا تقديم تخصص القالب للتجزئة:

#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س get() طريقة للوصول إلى المؤشر الخام:

NeuronWeightMap weights;
boost::shared_ptr<Neuron> n;

weights.find(n.get());

منذ أن تستخدم بالفعل دفعة، لماذا لا تستخدم boost::unordered_map لجدول التجزئة؟ انها تجمع خارج الصندوق shared_ptr للمفتاح، على الرغم من أنك تحقق أفضل كيفية القيام بذلك بشكل صحيح (boost.unordered.)

من التعليمات البرمجية أعلاه ما هو خطأ التحويل البرمجي؟

هل حاولت إعادة توجيه إعلان الخلايا العصبية للفئة؟

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؟

أجد عن طريق إضافة وظيفة hash_value ()، يمكنني استخدام shared_ptr كمفتاح في Stdext :: hash_map. أدناه أقارن باستخدام دفعة :: Unordered_Map مع STD :: 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() هو الأفضل منذ أن تعلن أنه مرة واحدة فقط في ملف الرؤوس الرئيسية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top