• 0
محمد علاء الدين

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

سؤال

كما هو واضح من السؤال، لدينا الدالة التاليه التى تقوم بالحصول على الجذر التربيعي لعدد صحيح، كيف يمكن تحويلها لـ 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 = ? ;
};

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

8 إجابة على هذا السؤال .

  • 0

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

لم أقم بتجربة الكود و لكن العملية مجرد تحويل التكرار إلى 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

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

هذه هي الطريقة باستخدام 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
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أهلا خالد،

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

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

تم تعديل بواسطه Khaled.Alshaya
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

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

تحياتي,

تم تعديل بواسطه Khaled.Alshaya
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
بالنسبة للصيغة, فهي الطريقة المعتادة أخ محمد

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

تم تعديل بواسطه Khaled.Alshaya
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .