الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيف يمكن تحويل هذه الداله إلى template class

بدأه C++er في 15 أكتوبر 2011 · 8 رد · 812 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

كما هو واضح من السؤال، لدينا الدالة التاليه التى تقوم بالحصول على الجذر التربيعي لعدد صحيح، كيف يمكن تحويلها لـ template class:

unsigned isqrt(unsigned value)
{
    unsigned sq = 1, dlt = 3;

    while(sq<=value)
    {
        sq  += dlt;
        dlt += 2;
    }

    return (dlt>>1) - 1;
}

يمكنك تصميم اى عدد تريد من الـ class templates و لكن فى النهايه اريد واحده ادخل لها الرقم و بداخلها يوجد متغير به النتيجه مثل التالي:

template<unsigned value>
struct IntSqrt
{
    static const unsigned Value = ? ;
};

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#2

السلام عليكم....

لم أقم بتجربة الكود و لكن العملية مجرد تحويل التكرار إلى recursion:

#include <cstddef>
#include <iostream>

template <std::size_t value, std::size_t sq, std::size_t dlt>
struct isqrt_impl{
    static const std::size_t square_root = sq <= value ? isqrt_impl<value, sq+dlt, dlt+2>::square_root : (dlt >> 1) - 1;
};

template <std::size_t value>
struct isqrt{
    static const std::size_t square_root = isqrt_impl<value, 1, 3>::square_root;
};

int main(){
    std::cout << isqrt<25>::square_root << std::endl;
}
1
#3

هذه هي الطريقة باستخدام constexpr, أجدها أسهل للإنسان الطبيعي العاقل من اللعب مع الـ structs :lol: قمت بتجربتها و تعمل بشكل سليم, و سأحاول جعل النسخة الأولى تعمل!

constexpr std::size_t isqrt_impl
    (std::size_t sq, std::size_t dlt, std::size_t value){
    return sq <= value ?
        isqrt_impl(sq+dlt, dlt+2, value) : (dlt >> 1) - 1;
}

constexpr std::size_t isqrt(std::size_t value){
    return isqrt_impl(1, 3, value);
}

int main(){
    std::cout << isqrt(24) << std::endl; // prints: 4
}

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 16 أكتوبر 2011 في 00:54

1
#4

أهلا خالد،

كود الـ struct يسبب overflow للمترجم و لم استطع ايجاد حل له، أيضا constexpr لم يتم دعمها من قبل العديد من المترجمات لذا بإستخدامها سجعل الكود المكتوب مقتصر على فئه معينه منهم.

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#5

و الله يا أخ محمد كنت سأقوم بكتابة نسخة مشابهة للإجابة المطروحة في SO لأنني حقيقة لم أكتب recursive template بدون specialization من قبل و لكن لم أتوقع أن كتابتها بهذا الشكل غير ممكنة في ++C! و لكن بالفعل سؤالك فتح أفق جديد بالنسبة لي في ++C. لم أكن أعلم أن الـ templates في ++C ليست Lazy Evaluated و هذا يشرح سبب الخطأ بكل بساطة. طرحت سؤالاً في SO و جاءت الإجابة و الحمدلله لتشرح السبب. شكراً لك على الموضوع القيم.

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 17 أكتوبر 2011 في 19:15

1
#6

جزاك الله خيرا اخى خالد، الحل فعلا غريب لم ارى مثل هذه الصيغه من قبل - و لم اجربها بعد، بالنسبه لـ constexpr هل يمكن تطبيقها على الداله الأصليه؟

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#7

لا أخ محمد, و إلا احتجنا "لمفسر" كامل لـ ++C يعمل وقت الترجمة. constexpr هي عبارة عن subset من ++C, بحيث أنها تسمح بـ return و عبارة بعدها, و لكن الـ recursion مسموح و الـ conditional مسموح, فهي لغة برمجة كاملة يمكنك فعل أي شيء تريده(لا يعتمد على مدخل أو مخرج وقت التشغيل بالطبع). بالطبع يمكنك استخدامها مع متغيرات وقت التشغيل و لكنها في تلك الحالة تنفذ وقت التشغيل و ليس وقت الترجمة. لذلك ليس هناك حاجة لكتابة نسختين من الدالة رغم أنه من الممكن فعل ذلك لاستخدام الحلقات, لأنها أفضل بالطبع من الـ recursion.

بالنسبة للصيغة, فهي الطريقة المعتادة أخ محمد, و الحقيقة لم أكن أعرف أن الـ templates ليست lazy!!! عندما كتبت المثال, كنت أتوقع أن الخطأ من الكود الذي كتبته و لكن عندما جاءت الإجابة في SO تذكرت أنني فعلاً لم أقم بكتابة أي meta function بهذه الطريقة أبداً! طريقة الـ specialization عبارة pattern matching توجد في لغات أخرى عديدة كـ run-time feature و لكنها غير موجودة في ++C غير في الـ metaprogramming!

تحياتي,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 17 أكتوبر 2011 في 21:21

#8
اقتباس
بالنسبة للصيغة, فهي الطريقة المعتادة أخ محمد

كتابة template type و عمل full specialization او partial specialization منه أنا اعرفها اما كتابة الـ declaration فقط لـ template type و اجراء specialization عليه دون كتابة الـ definition فهذه معلومه لم اعرفها من قبل!!!

مدونتي: C++ Tips and Tricks

#9

عندما تقوم بعمل declaration فإن الـ specializations المعرفة فقط هي المسموحة و إلا يصدر خطأ, و في هذه الحالة بالذات لا فرق, لأن هناك قيمتان true و false. قام بكتابة الأمر بطريقة أنيقة لا أكثر بدلاً من أن تكون false(أو true إذا أردت) هي الـ generic definition.

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 17 أكتوبر 2011 في 21:59

1

مواضيع مشابهة