سؤال

أرغب في الحصول على هيكلين يشيران إلى بعضهما البعض.وعلى وجه التحديد، أود الحصول على ما يلي:

template<typename Key, typename Value> 
class MyStructure {
public:
  typedef map<Key, list<pair<Value, typename ListType::iterator>>> MapType;
  typedef list<typename MapType::element_type::iterator> ListType;
private:
  MapType map_;
  ListType list_;
}

من الواضح أن هذا لن ينجح نظرًا لأنه لم يتم الإعلان عن ListType مسبقًا كنوع.كيف أستطيع فعل هذا؟كما ترون أنا أستخدم أنواع التكرار كمؤشرات لعناصر هذين الهيكلين.

كنت أفكر في استخدام نمط القالب المتكرر المثير للفضول، لكن لم أتمكن من الوصول إلى أي مكان به.اقترح أحد الأشخاص في ##c++ أيضًا استخدام الأسماء المستعارة للقالب، لكن ذلك فشل أيضًا (على الأقل، لا أعرف كيفية استخدام هذه الفكرة).

هل أفعل شيئًا خاطئًا من الناحية المفاهيمية؟أو ربما "لا يتوافق مع مفاهيم C++"؟يمكنني بالتأكيد القيام بذلك باستخدام void*s، لكنني أحاول أن أجعل الأمور بالطريقة الصحيحة :)

شكرًا!

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

المحلول

على الرغم من أنني شككت في أن هذا قد يكون نسخة مكررة (وهو كذلك من نواحٍ عديدة)، "تحياتي وهث.- Alf" محق في الإشارة إلى أن السؤال المكرر المحتمل يتعلق على وجه التحديد باستخدام typedef لهذا النوع من الشيء.

ومع ذلك، في السؤال الحالي، يرغب البروتوكول الاختياري في معرفة كيفية التعامل بشكل عام مع التضمين المتبادل في السيناريو الموضح في السؤال.

وهنا اقتراح:

#include <list>
#include <map>

template <typename Key, typename Value>
class MyElement;

template <typename Key, typename Value>
class MyStructure
{
public:
  typedef std::map<Key,MyElement<Key,Value> > MapType;
  typedef std::list<MyElement<Key,Value> >    ListType;
};

template <typename Key, typename Value>
class MyElement {
public:
  typename MyStructure<Key,Value>::MapType::iterator  map_iterator;
  typename MyStructure<Key,Value>::ListType::iterator list_iterator;
};

كما ترون، لقد قدمت نوع بيانات جديد MyElement, ، الذي يحتوي على مكرر القائمة بالإضافة إلى مكرر الخريطة.نظرًا لأن هذه فئة وليست typedef، فيمكن التصريح عنها للأمام.

نصائح أخرى

وهذا للأسف غير ممكن، بالطريقة التي تعبر بها عن ذلك.

من ناحية أخرى، يبدو لي أنه (نظرًا لمتطلباتك) يمكنك عكس عملية التخزين.

ماذا لو استخدمت أ list التابع Values, ثم هل كانت الخريطة تشير إلى هذه القائمة؟

وهذا من شأنه كسر التبعية الدورية.

typedef std::list< std::pair<Key, Value> > ListType;
typedef std::multiset<typename ListType::iterator, CmpFirst> MapType;

(لست متأكدًا مما إذا كنت قد فهمت حقًا ما كنت تحاول تحقيقه بالرغم من ذلك ...)

الحل الآخر الذي ربما ينبغي عليك مراعاته هو معرفة ما إذا كان بإمكانك التعبير عن ذلك من حيث Boost.MultiIndex.عندما تكون هناك حاجة إلى عدة تكرارات/أنماط بحث، غالبًا ما يكون Boost.MultiIndex بديلاً أفضل من الحل المصنوع يدويًا، لأنه يقوم بتشذير الفهارس داخل القيم لتقليل التخزين.يعد الاتساق الإضافي (أي وجود جميع الفهارس التي تشير إلى نفس مجموعة العناصر) أمرًا معطى.

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