كيف يمكنني استخدام نوع مخصص للمفاتيح في دفعة :: Unordered_map؟

StackOverflow https://stackoverflow.com/questions/1829639

سؤال

أنا أستخدم تنفيذ دفعة لعلاج خريطة التجزئة في مشروع الآن، وأنا أحاول تنفيذ نوع مخصص للمفاتيح. لدي أربعة أعداد صحيحة غير موقعة التي أرغب في الجمع بين Datatype 128 بت واحد لاستخدامها كإجراء.

لقد قمت بإنشاء بنية مع مجموعة عدد صحيح 32 بت من أربعة عناصر، والتي تعمل كتخزين بلدي. أن نكون صادقين، لست متأكدا من كيفية عمل خريطة التجزئة في التعزيز، لذلك لست متأكدا مما أفعله هنا، لكنني تابعت وثائق دفعة (http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html.) لتوسيع نطاق دفعة :: هاش، وأنا أنشأت وظيفة تجزئة، وكذلك مشغل مقارنة مخصص.

لدي هذا النوع المخصص المحدد في رأس. هذا هو رمزي:

#ifndef INT128_H_
#define INT128_H_

// Custom 128-bit datatype used to store and compare the results of a weakened hash operation.
struct int128
{
    unsigned int storage[4];

    /* Assignment operation that takes a 32-bit integer array of four elements.
    This makes assignment of values a shorter and less painful operation. */
    void operator=(const unsigned int input[4])
    {
        for(int i = 0; i < 4; i++)
            storage[i] = input[i];
    }
};

bool operator==(int128 const &o1, int128 const &o2)
{
    if(o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
       o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3])
        return true;

    return false;
}

// Hash function to make int128 work with boost::hash.
std::size_t hash_value(int128 const &input)
{
    boost::hash<unsigned long long> hasher;
    unsigned long long hashVal = input.storage[0];

    for(int i = 1; i < 3; i++)
    {
        hashVal *= 37;
        hashVal += input.storage[1];
    }

    return hasher(hashVal);
}

#endif

الآن عندما أستخدم هذا النوع في الواقع في خريطة Boost غير مرتبة، يجمع الرمز الخاص بي، ولكنه فشل في الارتباط. يدعي الرابط أن لدي رمز محدد عدة مرات في العديد من ملفات الكائنات. أود حقا الحصول على نوع 128 بت العمل مع هذه الخريطة. أي نصائح حول ما أنا شد، أو طريقة أفضل للقيام بذلك؟

هل كانت مفيدة؟

المحلول

إن مشاركة الخريطة غير المرتبة هي عرضية تقريبا للمشكلة التي تواجهها. المشكلة الحقيقية هي أنك تحدد hash_value و operator== في كل ملف يتضمن الرأس أعلاه.

يمكنك علاج هذا إما:

  1. تحديد كلا تلك الوظائف المضمنة
  2. مجرد إعلانهم في الرأس

إذا قمت بذلك الأخير (وهذا ما تريد عادة)، فستحرقل تعريفات تلك الوظائف في .cpp ملف (أو أيا كان التمديد الذي تستخدمه لملفات المصدر C ++). ستقوم بعد ذلك بتجميع هذا الملف، واربط الكائن الناتج مع التعليمات البرمجية الأخرى التي تستخدم نوع INT128.

تحرير: لا يزال بإمكانك جعل منظف المقارنة، شيء مثل:

bool operator==(int128 const &o1, int128 const &o2)
{
    return o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
           o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3]);
}

نصائح أخرى

يدعي الرابط أن لدي رمز محدد عدة مرات في العديد من ملفات الكائنات.

أعلن وظائفك كما inline

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