أحتاج إلى قالب فئة صفيف C ++ ، وهو ثابت الحجم ، ويستند إلى المكدس ولا يتطلب مُنشئًا افتراضيًا

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

سؤال

لذلك ، لقد كنت أبحث في AROST :: Array ولكنه يتطلب تحديد مُنشئ افتراضي. أعتقد أن أفضل طريقة لملء هذه الصفيف بالبيانات ، ستكون من خلال طريقة push_back (const t &). إن تسميته مرات أكثر من الحجم (المعروف في وقت الترجمة) سيؤدي إلى تأكيد أو استثناء ، اعتمادًا على تكوين البناء. وبهذه الطريقة ستحتوي دائمًا على بيانات ذات مغزى. هل يعرف أي شخص تنفيذ فعال ومحمول وموثوق به لهذا المفهوم؟

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

المحلول

حسنًا ، كنت أعتقد أن شخصًا ما كان سيحضر الإجابة الآن ، ولكن يبدو أنه لا ، لذلك دعنا نذهب.

ما تتمناه هو شيء حلمت به: أ boost::optional_array<T,N>.

هناك نوعانان:

  • أولا: على غرار boost::array< boost::optional<T>, N >, ، هذا هو كل عنصر قد يتم تعيينه أو لا يتم تعيينه.
  • ثانياً: على غرار أ std::vector<T> (بطريقة ما) ، يتم تعيين كل العناصر التي تبدأ وكل ما يلي.

بالنظر إلى الأسئلة / التعليقات السابقة ، يبدو أنك ترغب في الثانية ، لكن الأمر لا يهم حقًا لأن كلاهما متشابهان تمامًا.

template <typename T, size_t N>
class stack_vector
{
public:
  bool empty() const { return mSize == 0; }
  size_t size() const { return mSize; }
  size_t capacity() const { return N; }
  size_t max_size() const { return N; }

  T& operator[](size_t i) { return *(this->pfront() + i); }
  /// ...

private:
  T* pfront() const { return reinterpret_cast<T*>(&mStorage); }

  std::aligned_storage< N * sizeof(T), alignof(T) > mStorage;
  size_t mSize; // indicate how many elements are set, from the beginning
};

دعونا نركز على تلك العمليات الخاصة جدًا:

template <typename T, size_t N>
void push_back(T const& t)
{
  new (this->pfront() + mSize) T(t); // in place construction
  ++mSize;
}

template <typename T, size_t N>
void clear()
{
  for (size_t i = 0; i != mSize; ++i)
  {
    (this->pfront() + i)->~T();
  }
  mSize = 0;
}

كما تلاحظ ، فإن الصعوبة الرئيسية هي أن تتذكر ما يلي:

  • إذا لم يتم بناء عنصر بعد ، فأنت بحاجة إلى إنشاء إنشاء جديد + نسخ بدلاً من المهمة.
  • يجب التخلص بشكل صحيح من العناصر التي تصبح "عفا عليها الزمن" (أي بعد العنصر الأخير) بشكل صحيح (أي يتم استدعاء مدمرهم).

هناك العديد من العمليات على حاوية STL التقليدية التي قد تكون صعبة التنفيذ. على vector, ، العنصر خلط (بسبب insert أو erase) ربما هي الأمثلة الأكثر صرامة.

لاحظ أيضًا أنه مع C ++ 0x و Pistumizer-Lists vector احصل على emplace_back لبناء عنصر مباشرة في مكانه ، وبالتالي رفع CopyConstructible الشرط ، قد يكون نعمة لطيفة تعتمد على قضيتك.

نصائح أخرى

boost::array<T, 12> ta; لا يختلف عن T[12] ta;; ؛ إذا لم تستخدم قائمة المهيمنة ، فسيتم إنشاء العناصر الافتراضية.

سيكون الحلول المشترك boost::array<T*, 12> ta; أو ربما boost::array<unique_ptr<T>, 12> ta;.

الطريقة الوحيدة للتخزين حسب القيمة هي النسخ ، لا توجد طريقة للتغلب على ذلك ... هذا ما تفعله قوائم التهيئة:

struct A {
    A(int i):_i(i){ cout << "A(int)" << endl; }
    A(const A& a){ cout << "A(const A&)" << endl; }
    ~A(){ cout << "~A()" << endl; }

    int _i;
};

int main(){
    boost::array<A, 2> ta = {{1, 2}};
}

هذا المخرجات:

A(int)
A(const A&)
A(int)
A(const A&)
~A()
~A()
~A()
~A()

http://codepad.org/vjgeqwk5

قد يكون تخزين دفعة :: البديل في دفعة :: صفيف؟ اجعل المعلمة الأولى int أو شيء من هذا القبيل ..

بمعنى آخر

boost::array<boost::variant<int, foo>, 6> bar;

حسنًا ، عليك أن تتعامل مع متغير ، لكنه مخصص ...

في C ++ 0x حصلت std::array<type, size> (ربما نفس المعزز :: صفيف). يمكنك تهيئة بيانات الصفيف باستخدام fill() أو std::fill_n():

std::array<int, 30> array;
array.fill(0);
boost::array<int, 30> barray;
std::fill_n(barray.begin(), 30, 0);

إذا كنت ترغب في الحصول عليها افتراضيًا في التعريف ، يمكنك استخدام COPY-CTOR:

static std::array<int, 30> const nullarray = {0, 0, 0, ..., 0}; // nullarray.fill(0);
// (...)
std::array<int, 30> array{nullarray};

لماذا يجب أن تقيم على المكدس؟ هل لديك أدلة تجريبية على إنشاء و reserveجي vector بطيء للغاية (باستخدام أ vector يبدو مثل الإجابة الواضحة)؟

حتى لو كان كذلك ، يمكنك إنشاء مجموعة من المتجهات التي تحتوي على مساحة مخصصة و swap واحدة من المتجهات المسبقة مسبقا في نسخة محلية. عندما تنتهي مع واحد محلي ، قم بتبديله مرة أخرى (مثل إلى حد كبير splice خدعة ل listس).

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