سؤال

لنفترض أن لدي hash_map ورمزًا مثل

// i is an iterator
i = hash_map.erase(i)

لكن STL الخاصة بدول مجلس التعاون الخليجي لا تُرجع المكرر في المسح، بل تُرجع الفراغ.الآن هو رمز مثل

hash_map.erase(i++)

آمنة (أي.لا يبطل المكرر أو يفعل أي أشياء أخرى غير متوقعة أو غير سارة)؟يرجى ملاحظة أن هذه خريطة hash_map.

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

المحلول

نعم، هذا هو آمن، لأنه سيكون قد تم تعيين قيمة i إلى القيمة التالية، قبل أن يتم مسح القيمة الحالية.

ووفقا ل الوثائق SGI حول حاويات تجزئته لا يحدث إبطال للغير عناصر -erased، ولا حتى لتغيير حجم (ليس هناك كلمة حول ما إذا كان الإدراج تسبب تغيير الحجم، بحيث أن نكون حذرين وأنا أعترف بأن هذا احتمال ممكن) --- ولكن في هذه الحالة، سيتم تغيير ترتيب التكرار. ولكن هذا لا ينطبق هنا، إلا إذا كنت الخروج من طريقك لتغيير حجم الحاوية أثناء اجتياز أو شيء من هذا. : -)

نصائح أخرى

يمكنك تغليف المسح لتوفير نفس الواجهة لجميع الحاويات التي تستخدمها:

namespace detail {
template<typename Container, typename R>
struct SelectErase {
  // by default, assume the next iterator is returned
  template<typename Iterator>
  Iterator erase(Container& c, Iterator where) {
    return c.erase(where);
  }
};
// specialize on return type void
template<typename Container>
struct SelectErase<Container, void> {
  template<typename Iterator>
  Iterator erase(Container& c, Iterator where) {
    Iterator next (where);
    ++next;
    c.erase(where);
    return next;
  }
};

template<typename I, typename Container, typename R>
SelectErase<Container,R> select_erase(R (Container::*)(I)) {
  return SelectErase<Container,R>();
}
} // namespace detail

template<typename Container, typename Iterator>
Iterator erase(Container& container, Iterator where) {
  return detail::select_erase<Iterator>(&Container::erase).erase(container, where);
}

وهذا يتطلب إما:

  1. يقوم c.erase بإرجاع المُكرِّر للعنصر التالي.هذه هي الطريقة التي تعمل بها المتجهات، وdeque، والقائمة.
  2. يقوم c.erase بإرجاع الفراغ ولا يبطل المكرر التالي.هذه هي الطريقة التي تعمل بها hash_map الخريطة، والضبط، و(غير stdlib).

وأكره أن المطر على العرض، ولكن لا أعتقد أن ما أقترحه هو آمن.

وأنا ++ هي المشغل بعد الزيادة، وهو ما يعني يتزايد انا بعد الدعوة لمحو. لكن محو يبطل كل التكرارات لافتا إلى العنصر يجري محوها. حتى في الوقت الذي يتزايد ط انها ليست صالحة أكثر من ذلك.

إذا كنت محظوظا فإنه قد عمل بشكل صحيح عن طريق الصدفة حتى يوم واحد لا أكثر من ذلك.

وكما بقدر ما أنا على علم لا توجد وسيلة حول هذا ولكن شيئا من هذا القبيل:

// tmp and i are both iterators
tmp = i;
++i;
hash_map.erase(tmp);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top