c++ - الطريقة الاصطلاحية لتمييز اثنين من صانعي الصفر




performance constructor (5)

أعتقد أن التعداد هو اختيار أفضل من فئة علامات أو منطقي. لا تحتاج إلى تمرير مثيل للبنية ومن الواضح من المتصل الخيار الذي تحصل عليه.

struct event_counts {
    enum Init { INIT, NO_INIT };
    uint64_t counts[MAX_COUNTERS];

    event_counts(Init init = INIT) {
        if (init == INIT) {
            std::fill(counts, counts + MAX_COUNTERS, 0);
        }
    }
};

ثم يبدو إنشاء مثيلات كما يلي:

event_counts e1{};
event_counts e2{event_counts::INIT};
event_counts e3{event_counts::NO_INIT};

لدي فئة مثل هذا:

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() : counts{} {}

    // more stuff

};

عادةً ما أرغب في الإعداد الافتراضي (صفر) لتهيئة مجموعة counts كما هو موضح.

ومع ذلك ، في المواقع المحددة التي تم تحديدها بواسطة التوصيف ، أود منع تهيئة المصفوفة ، لأنني أعلم أن المصفوفة على وشك الكتابة فوقها ، لكن المحول البرمجي ليس ذكيًا بدرجة كافية للتعرف عليها.

ما هي الطريقة الاصطلاحية والفعالة لإنشاء مثل هذا المنشئ الصفري "الثانوي"؟

حاليًا ، أستخدم uninit_tag فئة علامة يتم تمريرها كوسيطة وهمية ، مثل ذلك:

struct uninit_tag{};

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() : counts{} {}

    event_counts(uninit_tag) {}

    // more stuff

};

ثم أدعو مُنشئ عدم البدء مثل event_counts c(uninit_tag{}); عندما أريد أن قمع البناء.

أنا منفتح على الحلول التي لا تنطوي على إنشاء فئة وهمية ، أو أكثر فعالية بطريقة أو بأخرى ، إلخ.


أنا أحب الحل الخاص بك. ربما تكون قد فكرت أيضًا في بنية متغيرة ومتغيرة ثابتة. فمثلا:

struct event_counts {
    static constexpr struct uninit_tag {} uninit = uninit_tag();

    uint64_t counts[MAX_COUNTS];

    event_counts() : counts{} {}

    explicit event_counts(uninit_tag) {}

    // more stuff

};

مع متغير ثابت غير مهيأ منشئ دعوة قد يبدو أكثر ملاءمة:

event_counts e(event_counts::uninit);

يمكنك بالطبع تقديم ماكرو لحفظ الكتابة وجعلها أكثر من ميزة منهجية

#define UNINIT_TAG static constexpr struct uninit_tag {} uninit = uninit_tag();

struct event_counts {
    UNINIT_TAG
}

struct other_counts {
    UNINIT_TAG
}

إذا كان نص المنشئ فارغًا ، فيمكن حذفه أو تعطيله:

struct event_counts {
    std::uint64_t counts[MAX_COUNTERS];
    event_counts() = default;
};

ثم التهيئة الافتراضية event_counts counts; سيترك counts.counts غير مهيأ (التهيئة الافتراضية هي المرجع هنا) ، وتهيئة قيمة event_counts counts{}; سوف قيمة تهيئة counts.counts ، وملء بشكل فعال مع الأصفار.


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


قد ترغب في النظر في تهيئة مرحلتين للفصل الدراسي:

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() = default;

    void set_zero() {
       std::fill(std::begin(counts), std::end(counts), 0u);
    }
};

لا يقوم المنشئ أعلاه بتهيئة الصفيف إلى الصفر. لتعيين عناصر الصفيف إلى صفر ، يجب عليك استدعاء دالة العضو set_zero() بعد الإنشاء.







constructor