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

هل تستخدم Boost ؟

بدأه Khaled.Alshaya في 5 يوليو 2009 · 16 رد · 2,002 مشاهدة · في قسم المواضيع الهامة في قسم السي /سي++
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

هل تستخدم Boost ؟ باستمرار أم قمت بتجربتها ؟ لا تعرفها أصلاً ؟

شاركونا بخبراتكم حول هذه المكتبة :)

و اذكروا لنا أفضل ما جربتموه فيها.... و لا مانع من الإشارة إلى مكتبات متميزة بالإشارة إليها إن كان لكم معها تجربة...

تحياتي ....

#2

اقرب احتكاك ليا معاها كان من خلال C++ for Programmers

هى بالتأكيد بتحل مشاكل كتير يمكن مبرمجين السى++ يحسو انها godsend ويمكن يحسو انهم كانو عيشين فى دنيا تانية خاصة موضوع ال Smart pointers

ولكن الحقيقة مش بتقدم جديد لرجال ال dynamic languages B)

--عجبتنى جدا سهولة التعامل مع ال Regular Expressions مقارنة باستخدام PCRE

edit:

Building Hybrid Systems with Boost.Python

تم تعديل هذه المشاركة بواسطة ahmed_youssef في 5 يوليو 2009 في 07:56

(map share people)

فضلا لاتقم بمراسلتي من أجل أسئلة لها أقسامها في المنتدى حتى تعم الفائدة على الجميع وللحصول على إجابات أفضل من أعضاء أكثر خبرة.
Weblog
@bitbucket
@xmonader

#3

تبدو boost مكتبة رائعة

أقوم أحيانا بالأطلاع على شيفراتها, وتجربة بعض الأكواد

وأستمتع بتصفح الموقع الخاص بها,

ويبدو أني سأستخدمها قريبا في مشروع أعمل عليه,

أرجو من الله أن يوفقني لإكماله

والسلام عليكم

SAFETY TIP : Always delete what you new, and free what you malloc, never mix new with free or malloc with delete.

#4

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

يبدو أن boost مظلومة في عالمنا العربي كما هو الحال مع ++C :)

اقتباس
هى بالتأكيد بتحل مشاكل كتير يمكن مبرمجين السى++ يحسو انها godsend ويمكن يحسو انهم كانو عيشين فى دنيا تانية خاصة موضوع ال Smart pointers

صحيح :)

الـ smart pointers من أفضل المكتبات جودة في boost... و لكن هناك الكثير و الكثير الذي لا يمكن لشخص واحد أن يكتشفه كله...

حتى لا يختلط الأمر على الجمهور... boost ليست مكتبة لبناء التطبيقات السريعة...

boost مكتبة لبناء الأنظمة... (ليست أنظمة التشغيل, أي نظام :lol: )

سأتعرض في لمحة قادمة حول المكتبة و حول بعض مكتباتها بإذن الله :)

تحياتي ...

#5

قمت بتجربتها , جميلة وعمليّة , كنت متردد كثيراً في تجربتها لسببين :

1- لم أجد المكتبة مترجمة بالكامل ( binary ) .. حيث ترجمة source code مكلف جدّا .. وهذه وجدت حلّها في هذا الموقع

2- البرنامج سيتطلّب وجود هذه المكتبة , وأغلب المطوّرين لايتعاملون معها ( بعكس STL ) التي توجد بشكل افتراضي .. حيث سيضطر لتحميل المكتبة boost .. أتمنى أن يتم تضمينها يوماً ما بشكل افتراضي مع أي مترجم محترم .

بالمناسبة , قرأت في أحد ردودك أخي خالد عن مكتبة لوكي

أظن هكذا تنطق , عموماً , يوجد بها أمور جميلة , وجدت مثلاً طريقة سهلى لتطبيق نمط Factory , يبدو لي أنه مبني على static polymorphism , عموماً , هل يوجد للمكتبة boost مقابل لهذا , ماهي مميزات " لوكي " , أتحفنا بالمزيد عنها .

1. Factory< AbstractProduct, int > aFactory;
2. aFactory.Register( 1, createProductNull );
3. aFactory.CreateObject( 1 );

تم تعديل هذه المشاركة بواسطة الشمري في 7 يوليو 2009 في 22:55

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#6

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

للأسف أخي الشمري, تصفحت الكتاب فقط و رأيت بعض الكلام عن الـ smart pointers في loki و لكني لم أجربها حتى الآن, عموماً مصممها نار على علم :)

مثال بسيط جداً من Boost ربما ابسط أدوات Boost على الإطلاق :)

على الأقل لكي نبدأ الكلام حولها في المنتدى ....

انظر إلى قطعة الكود التالية شديدة البراءة, و قل هي تبدو لك بريئة أم غير ذلك ::

std::ifstream* input = new std::ifstream("test.txt");
SomeFunction(input); // this function may 'throw' an exception.
delete input;

أول نظرة ستعطيك قمة البراءة, و هي أصلاً تخفي ورائها كارثة حقيقية في التعامل مع الذاكرة....

لو أطلقت الدالة SomeFunction أي Exception فإنه سيتم الخروج من الدالة على الفور! و استدعاء destructors جميع الكائنات الحية, أقول الكائنات الحية فقط... نحن لدينا "مؤشر" و المؤشرات في ++C ليس لها تأثير جانبي destructor عند انتهاء حياتها..

بالتالي فإن السطر الذي سنقوم بإلغاء الذاكرة فيه لن يصل إلى التنفيذ, و ضاعت الذاكرة التي حجزناها في أول سطر :)

عموماً, Boost وفرت شيء اسمه scoped_ptr, بسيط جداً, لايمكنك نسخه إي إسناده على الإطلاق لمؤشر آخر حتى ولو من نفس نوعه...

الفائدة منه أننا نقوم بحجز الذاكرة عن طريقه, و يتكفل هو بالباقي, و لو حصل أي شيء فإنه سيلغي ذاكرته حال الخروج من الدالة التي يوجد فيها,

لاحظ كيف سيصبح كودنا صحيحاً في المثال التالي ::

boost::scoped_ptr<std::ifstream> input(new std::ifstream("test.txt"));
SomeFunction(input); // this function may 'throw' an exception.
// even if the function throwed an exception, the destructor will be called.

مهما حصل, فأنت تضمن أن الذاكرة ستعاد إلى النظام "مهما حصل".

طبعاً المثال الذي في الأعلى سخيف و هو للتوضيح فقط, و إلا في ++C الحديثة, فأنت لا تتعامل مع المؤشرات أصلاً, و المثال الذي مررنا عليه كان يجب كتابته على النحو التالي ::

std::ifstream input("test.txt");
SomeFunction(input); // this function may 'throw' an exception.
// even if the function throw an exception, the destructor will be called.

هذه الطريقة أفضلهم, لأنك تقوم بإنشاء input على أنها متغير عادي على الـ stack, كأنها int أو double أو أي نوع primitive في ++C... أي أنك تقوم بإنشاء الكائنات على الـ stack و تترك مهمة التنظيف ورائك للمترجم الذي سيقوم بإدراج بعض الكود

لتحريك مؤشر الـ stack حسب المطلوب.... و على الكائن أن ينظف وارء نفسه, سواء قام بطلب ذاكرة من الـ heap أو حتى أي نوع من المصادر كالشبكة أو فتح ملفاً في نظام التشغيل فعليه إغلاقه,

تسمى هذه الطريقة RAII أي "الكائن الذي يأخذ شيئاً هو الذي يمتلك حق التصرف فيه".

اقتباس
1- لم أجد المكتبة مترجمة بالكامل ( binary ) .. حيث ترجمة source code مكلف جدّا .. وهذه وجدت حلّها في هذا الموقع

حسناً معك حق, و لكن هذه هي العادة في المشاريع المفتوحة... و السبب أنها تعمل على عدد منصات هائل حقيقية... و لكن انتظر :wink:

إذا كنت استخدمت VC فهو سطر واحد :happy: و أنصحك أيضاً بالتعرف على bjam الذي استخدمته في بناء boost فهو من boost نفسها....

قم بكتابة الـ makefile مرة و ترجم على أي مترجم :wink:

و الشيء الآخر, "معظم" boost عبارة عن headers لأنها تعتمد بشكل رئيسي على الـ metaprogramming, و لكن هناك بعض المكتبات التي بالفعل تحتاج إلى بناء...

----------------------------------------------

يبدو أنك استعملت برنامج التحميل الخاص بـ boost هو في الحقيقة أقدم بـ minor version عادة, و بناء المكتبة سنستعرضه قريباً بإذن الله هو عبارة عن سطر واحد :)

--------------------------------------------

اقتباس
2- البرنامج سيتطلّب وجود هذه المكتبة , وأغلب المطوّرين لايتعاملون معها ( بعكس STL ) التي توجد بشكل افتراضي .. حيث سيضطر لتحميل المكتبة boost .. أتمنى أن يتم تضمينها يوماً ما بشكل افتراضي مع أي مترجم محترم .

الحقيقة أنا مستغرب, اذهب إلى Stackoverflow و انظر إلى الإجابات, أعتقد أن 90% من مطوري ++C يستخدمون boost... و حتى أن cpp0x ضمت بعض مكاتبها لكي تصبح من ضمن المكتبة القياسية,عموماً هي مكتبة قياسية فعلياً,

صحيح أني لم أستخدمها منذ مدة طويلة, و لكن بالفعل العمل معها غير :)

إن شاء الله نلقي الضوء على بعض النقاط هنا و هناك,

تحياتي ...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 8 يوليو 2009 في 01:34

#7

جزاك الله خيرا استاذ خالد على هذه المقدمة البسيطة واتمنى منك الاستمرار فى الدروس حول ال boost بقدر الامكان وتوضيح مدى امكانياتها

amdvsintel22.jpg

--i use AMD--

لا اله الا الله محمد رسول الله

أستعن بالله و لا تعجز

تابعنى على تويتر

***

#8

حسناً لنلقي الضوء على أداة صغيرة أخرى في Boost حتى نتعرف عليها أكثر :)

أولاً, كم مرة رأيت سؤالاً في هذا المنتدى أو غيره عن كيفية تحويل الأعداد إلى نصوص و العكس ؟

ستجد معظم الإجابات تتركز حول مكتبة C في الحقيقة و استخدام itos و أخواتها :)

مع أن ++C وفرت طريقة سوبر سهلة و آمنة 100% إلا أن المبرمجين لم يستخدموها, لسبب واحد سنذكره في نهاية الكلام.

أولاً لنرى ماذا تقدم لنا Boost :wink:

هناك شيء في Boost يسمى lexical_cast, يعني محول "نصي", هذا مثال على الـ lexical_cast ::

#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>

int main()
{
	using namespace std;
	using namespace boost;

	string ageString, salaryString;
	int age;
	double salary;

	cout << "Enter your age: ";
	cin >> age;
	cout << "Enter your salary: ";
	cin >> salary;

	ageString = lexical_cast<string>(age);
	salaryString = lexical_cast<string>(salary);
	// Done!

	return 0;
}

هل ترى السهولة ؟ تضع النوع الذي تريد التحويل إليه و تمرر الشيء الذي تريد التحويل منه!

lexical_cast<To>(From);

في المثال قمنا بالتحويل from عدد إلى to نص :)

يمكنك التحويل بالعكس, من نص إلى عدد بنفس الطريقة....

هناك إضافة بسيطة تصور أن النص الذي تحوله إلى عدد, لا يمثل عدداً في الحقيقة إنما بيانات عشوائية, على سبيل المثال ::

string x = "x254";
int number = lexical_cast<int>(x);

عملية التحويل لن تتم! كيف سيقوم lexical_cast بإخبارنا ؟ عن طريق exception اسمه bad_lexical_cast, حتى و لم تكن استخدمت الـ exceptions من قبل الأمر بسيط جداً, هذا مثال ::

string x = "x254";
try
{
	int number = lexical_cast<int>(x);
}
catch(bad_lexical_cast& )
{
	cout << "This line will be written!";
}

ضع عملية التحويل داخل try و قم باستلام الـ exception في catch و تصرف على هذا الأساس :)

سهل جداً حسبما أعتقد حتى الآن, و لكن هناك شيء مميز في هذا الأداة حقاً و إلا لما كانت من Boost :)

هل تذكر عملية التحويل من double إلى int في ++C ؟ مثلاً ::

int number = static_cast<int>(196.22);

الآن قارن lexical_cast مع static_cast :)

string data = "25.5";
double real = lexical_cast<double>(data);
int	age  = static_cast<int>(real);

هل ترى هذا أحد فنون الـ metaprogramming :) على الرغم أن static_cast هي من اللغة نفسها, بينما lexical_cast ليس إلا كائناً قمنا ببنائه, إلا أنه بإمكاننا محاكاة اللغة بشكل لا يصدق!

عموماً إذا كان لديك رغبة بمعرفة كيفية فعل مثل هذا الشيء, انظر إلى رد الأخ الشمري في الموضوع التالي, و لا ننسى أن نشكر الأخ محمد الذي فتح الموضوع أصلاً ::

Function Templates

ربما تعرف أن المكتبة القياسية فيها أداة تسمى stringstream يمكنك عن طريقها تحويل النصوص إلى أعداد و العكس بسهولة بالغة جداً :)

فمثلاً لتحويل نص إلى عدد ::

string salaryString = "5000.756987455";
double salary;
stringstream convertor;

convertor << salaryString;
convertor >> salary;

هل ترى عدد السطور للقيام فقط بما عملناه ببـ lexical_cast ؟

عدد أكثر بكثير, و لكن هل هذا يعني أن stringstream سيئة ؟ لا على الإطلاق, في الحقيقة lexical_cast مبنية فوق هذا العفريت المسمى stringstream :)

سأقول لك متى ستحتاجه, عندما تريد ضبط عمليات الإخراج بكامل خصائصها... فمثلاً ::

#include <iomanip> // for setprecision
.
.
.

string salaryString;
double salary = 5000.75698;
stringstream convertor;

convertor << setprecision(6) << salary;
convertor >> salaryString;

أنا أستخدمه عندما أريد أن أقوم بعمل formatting لمجموعة من البيانات و من ثم اخراجها على شكل نص, أو عندما أقوم بعملية parsing بسيطة لنص ما :)

بالطبع Boost أنقذت مبرمجي ++C من التعامل المخيف مع النصوص الذي كان يحصل في C و ستجد فيها من السكين إلى المدفع حينما يتعلق الأمر بالنصوص...

تحياتي ....

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 8 يوليو 2009 في 16:43

#9

جميل , أظن هذا يدفعنا لترك مخلفات السي sprintf و atoi وراءنا ..

في البداية اختلط الامر لدي , يوجد هناك شيء اسمه numeric_cast ، هذا اذاً مخصص للتحويل بين أنواع الأرقام ( float - int - double الخ ) , وهناك نوع اخر , الذي تفضّلت بشرحه , هو للتحويل من نصوص الى أرقام وبالعكس .. اممم :

#include <iostream>
#include "boost/cast.hpp"
#include "boost/limits.hpp"
#include <boost/lexical_cast.hpp>




int main() {


  std::string str;
  int	_i = std::numeric_limits<int>::max();
  double _d = 10000.1234;
  try
  {
	str = boost::lexical_cast<std::string>(_i);
	_i  = boost::numeric_cast<int>(_d);
	std::cout << " str : " << str << " ,   _i = " << _i << std::endl;
  }
  catch (std::exception & e)
  {
	  std::cout <<  e.what() << std::endl;	
  }
}

بالمناسبة ,, أثناء تطبيقي لمثالك أخي خالد , كتبت التالي :

#include <iostream>
#include "boost/cast.hpp"
#include "boost/limits.hpp"
#include <boost/lexical_cast.hpp>

int main() {


  std::string str;
  try
  {
	str = boost::numeric_cast<std::string>(10);
	std::cout << " str : " << str << std::endl;
  }
  catch (std::exception & e)
  {
	  std::cout <<  e.what() << std::endl;	
  }
}

ظهرت لدي أحد أشكال الأخطاء الجميلة .. استمتع بالنظر اليها ..

1>I:\Program Files\boost\boost_1_38\boost/numeric/conversion/converter_policies.hpp(179) : error C2440: 'static_cast' : cannot convert from 'int' to 'std::basic_string<_Elem,_Traits,_Ax>'

1> with

1> [

1> _Elem=char,

1> _Traits=std::char_traits<char>,

1> _Ax=std::allocator<char>

1> ]

1> No constructor could take the source type, or constructor overload resolution was ambiguous

1> I:\Program Files\boost\boost_1_38\boost/numeric/conversion/converter_policies.hpp(179) : while compiling class template member function 'std::basic_string<_Elem,_Traits,_Ax> boost::numeric::raw_converter<Traits>::low_level_convert(int)'

1> with

1> [

1> _Elem=char,

1> _Traits=std::char_traits<char>,

1> _Ax=std::allocator<char>,

1> Traits=boost::numeric::conversion_traits<std::string,int>

1> ]

1> I:\Program Files\boost\boost_1_38\boost/numeric/conversion/detail/converter.hpp(509) : see reference to class template instantiation 'boost::numeric::raw_converter<Traits>' being compiled

1> with

1> [

1> Traits=boost::numeric::conversion_traits<std::string,int>

1> ]

1> I:\Program Files\boost\boost_1_38\boost/numeric/conversion/converter.hpp(35) : see reference to class template instantiation 'boost::numeric::convdetail::non_rounding_converter<Traits,RangeChecker,RawConverter>' being compiled

1> with

1> [

1> Traits=boost::numeric::conversion_traits<std::string,int>,

1> RangeChecker=boost::numeric::convdetail::dummy_range_checker<boost::numeric::conversion_traits<std::string,int>>,

1> RawConverter=boost::numeric::raw_converter<boost::numeric::conversion_traits<std::string,int>>

1> ]

1> I:\Program Files\boost\boost_1_38\boost/numeric/conversion/cast.hpp(41) : see reference to class template instantiation 'boost::numeric::converter<T,S>' being compiled

1> with

1> [

1> T=std::string,

1> S=int

1> ]

1> .\Main.cpp(16) : see reference to function template instantiation 'Target boost::numeric_cast<std::string,int>(Source)' being compiled

1> with

1> [

1> Target=std::string,

1> Source=int

1> ]

حاول Visual C أن يجعل رسالة الخطأ أكثر جمالاً فقال :

Error C2440: 'static_cast' : cannot convert from 'int' to 'std::basic_string<_Elem,_Traits,_Ax>' I:\Program Files\boost\boost_1_38\boost\numeric\conversion\converter_policies.hpp 179

بالنقر مرّتين على رسالة الخطأ .. أجد نفسي في الملف converter_policies.hpp في السطر 179 :

  static result_type low_level_convert ( argument_type s ) { return static_cast<result_type>(s); }

طبعاً تشكر المترجم .. وتقول له .. اصمت رجاءً .. وتحاول أن تصلح الخطأ بنفسك :D .

لذلك هذه أحد عيوب Template , رسائل الخطاء بشعة .. أضف هذا السبب للأسباب المنصرمة :D ، لكن لايعني هذا هجر هذه المكتبة الجميلة بسبب هذا السبب البسيط .. نأمل أن يتحسّن عرض الاخطاء مع الوقت .

ننتظر المزيد أخي خالد .. يجب دفع مبرمجي السي بلس دفعاً نحو العصر الحديث .. أعرفهم جيداً .. يتمسّكون كثيراً بالعادات الموروثة من لغة السي.. ;)

تم تعديل هذه المشاركة بواسطة الشمري في 9 يوليو 2009 في 00:26 — السبب: تعديل numberic الى numeric , غلطة مطبعية

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#10

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

ضحكت كثيراً عندما رأيت رسالة الخطأ :lol:

اقتباس
في البداية اختلط الامر لدي , يوجد هناك شيء اسمه numberic_cast

حسناً numeric_cast يختلف, الجميل فيه أنه بإمكانك معرفة حصول الـ overflow بسهولة بالغة دون الإعتماد على منصة معينة... فمثلاً نريد نسخ قيمة من متغير int إلى متغير char! هل يتسع هذا الـ char لهذه القيمة ؟ أم سيحصل overflow ؟

سيصبح التعامل عن طريق الـ exceptions بكل سهولة :)

للأسف رسائل الخطأ البشعة جداً سببها أن الـ templates لغة برمجة :)

و رسائل الخطأ الصادرة عن الـ templates رغم أنها طويلة جداً إلا أنه مع التعود بإمكانك "فك تشفيرها" :lol:

للأسف لن يدعم VC 2010 الـ Concepts :( لأنها النقلة النوعية الجديدة في عالم ++C. معها ستصبح أخطاء الـ templates في ++C كأخطاء الـ interfaces في Java عندما تنسى مثلاً الدالة المطلوبة للـ interface... أعتقد أن هذا هو ما تريده :wink:

بكل بساطة ما يحصل الآن, هو أن المترجم يخبرك "بمكان" الخطأ, و لا يخبرك بالخطأ نفسه....

لماذا و كيف تم إصلاح هذه العلة يصلح لكي يكون مقدمة عن الـ Concepts التي لن نراها قريباً, و لكن لا ضير من التعرف عليها حتى وصولها,

بإذن الله في رد قادم سنطلع على كيفية "فك شفرة" رسالة الخطأ التي ظهرت لديك :)

تحياتي ,,,

#11
اقتباس
I:\Program Files\boost\boost_1_38\boost/numeric/conversion/converter_policies.hpp

الأخ الشمري, ارحم جهازك يا رجل

نظام التشغيل على القرص I :unsure:

C D E F G H I

القرص I رقمو 7 :blink:

وما خفي أعظم, الله اعلم شو في غيرو أقراص :S

SAFETY TIP : Always delete what you new, and free what you malloc, never mix new with free or malloc with delete.

#12
اقتباس
وما خفي أعظم

أين الـ K و J يا رجل :D

لاتعتقد أن الاحجام كبيرة , لكن أفعل ذلك لتقليل فرص خسارة البيانات , ولأني أملك أكثر من نظام تشغيل .. كفئران تجارب ..

عموماً .. لازلنا نترّقب الاخ خالد وهو يفك ترميز شفرة الخطأ :D ... مشكور أخوي خالد وزادك الله من العلم النافع .

تم تعديل هذه المشاركة بواسطة الشمري في 13 يوليو 2009 في 00:30

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#13

ما دام إنكم تتحدثون عن المكتبة boost فحبيت أدلو بدلوي الفاضي :lol: .

المكتبة هذه منزلها على جهازي , لكن ما قد كتبت برنامج يعتمد عليها كل إعتمادي كان على الSTL أو كود أنا أكتبته , المهم من الأشياء اللي عجبتني في المكتبة هي lexical_cast بصراحة طريقة سهلة للتحويل من وإلى أي نوع من الstring . وهذه أحد أكبر المشاكل في مكتبة ال++C . لأنه لا توجد طريقة سهلة لعمل مثل هذه العمليات التي ربما هي بسيطة لكن في واقع الأمر هي أكثر من مهمة خصوصاً الذي قد قام بكتابت ًWindows Application .

أو من جرب الطريقة ToString في الC# أو الJava . يرى بسطاة هذه الدوال وفاعليتها . لكن المشكلة ؟!!!!!

أن lexical_cast ماهي إلا تغليف لStrstream .... وهذه الأخيرة رغم سهولتها في الإستخدام إلا أنه لدي تحفظ كبير على الأداء لها . فهو كائن مخصص أصلا لتنسيق المخرجات وبالتالي لا يستحب إستخدامه داخل العمليات , ما لم تقوم بطباعة التجهيز للطباعة .

فما رأيكم بالنسبة لما قلت ...

تم تعديل هذه المشاركة بواسطة b.m.s في 13 يوليو 2009 في 02:01

#14

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

عذراً على التأخير, الدوام الصيفي غير ممتع مع الحرارة الرائعة :wacko:

اقتباس
عموماً .. لازلنا نترّقب الاخ خالد وهو يفك ترميز شفرة الخطأ

أخي الشمري, دعنا نحلل رسالة الخطأ حتى نستعرض كيفية فهم تلك الرسائل أو حتى اقتناص معنى الخطأ, رغم صعوبة المهمة :)

أولاً, أول سطر لديك في الخطأ هو التالي ::

Error C2440: 'static_cast' : cannot convert from 'int' to 'std::basic_string<_Elem,_Traits,_Ax>' I:\Program Files\boost\boost_1_38\boost\numeric\conversion\converter_policies.hpp 179

هذه هي زبدة الخطأ, و الباقي عبارة عن سرد "مكان" الخطأ في الكود لا غير, مع توضيح قيمة الـ template parameters وقت حصول الخطأ.

ما تقوله لنا هو أن static_cast لا يمكنها تحويل int إلى الـ template class المسمى basic_string و يذكر الخطأ الـ template parameters بعد أول سطر ::

1> with

1> [

1> _Elem=char,

1> _Traits=std::char_traits<char>,

1> _Ax=std::allocator<char>

1> ][/::

الآن ما هو الخطأ ؟!

في الحقيقة أن الخطأ يتعلق بـ static_cast.

class Integer
{
	int x;

public:

	Integer(const int& vX) : x(vX)
	{ }

	operator int()
	{
		return x;
	}
};

int main()
{
	Integer x = 5;
	int y = 9;

	y = static_cast<int>(x); // operator int()

	y = 609;

	x = static_cast<Integer>(y); // Integer(const int& vX)

	return 0;
}

كل ما تحتاجه هو Copy Constructor كما في المثال, و Conversion Operator كما في المثال أيضاً, و تستطيع التحويل بين النوعين بسلاسة عن طريق static_cast :)

كما تعرف فـ string ليس به copy ctr يستقبل int و ليس به أيضاً conversion operator يرسل int.

بالتالي فإن عملية التحويل غير معرفة و يصدر الخطأ....

حسناً, لماذا رسالة الخطأ الطويلة العريضة التي رأيناها مادام الخطأ بهذه البساطة ؟

تخيل أن القطعة التي في مترجم ++C هي عبارة عن interpreter للحظة, تقوم بتفسير شيء اسمه templates :)

عندما يصل هذا المفسر الذي يفسر برنامجنا المكتوب بالـ templates و مخرجات هذا البرنامج عبارة عن كود ++C,

فإنه سيصادف خطأً كما في مثالك الذي عرضته, بالتالي سيقوم بإخراج الـ state لحظة الخطأ, كل ما يقوم به ببساطة عبارة

عن dump للحالة وقت الخطأ :)

أتمنى أن يكون هذا مفهوماً لأني أعقد الأمور أحياناً :)

و لكن, هناك خطأ كبييييييييييييير في الموضوع, ليس في مثالك بل في مفهوم الـ templates نفسها,

هل استخدمت الـ static_cast ؟

الإجابة :: لا

لماذا الخطأ إذاً حول static_cast ؟

انظر إلى ردي هنا في الموضوع الذي تناقشنا فيه أنا و الأخ متميز

الـ templates حالياً أنواعها (على سبيل المثال T غالباً ما تستخدم) dynamic, أي أن النوع لا يتم التحقق منه إلا لحظة تنفيذ الـ template code,

لذلك فإن أي خطأ, يصدر بعد ترجمة كود الـ templates عند محاولة مترجم ++C ترجمة الكود الناتج.

ما نريده هو أن تصبح الأنواع في الـ templates كالـ interfaces في OOP الموجودة في Java و #C و لكن مع فروق :wink:

بإذن الله سأفتح موضوعاً حول الـ Concepts في القريب العاجل :)

قبل أن أنسى, هل يجب عليك كمبرمج ++C أن تعرف كل هذا عن الـ templates ؟

الحقيقة أنه لا يجب حتى لو كنت محترفاً,

لأن ذلك أصلاً موجه لكتابة المكتبات و ليس للبرمجة العادية, لم أكتب حتى الآن شيئاً مفيداً بالـ templates لأني لست مؤهلاً لكتابة مكتبات برمجية حقيقية :) و كل ما لدي هو معلومات عامة,

لذلك إن صادفت شيئاً كالـ Concepts و غيرها في ++C فهي ليس من الأساسيات, و إنما موجهة لمبرمجي المكتبات و هؤلاء بالطبع خبراء برمجة و ليسوا طلاب مثلي :lol:

تحياتي ...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 14 يوليو 2009 في 01:29

#15

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

اقتباس
أن lexical_cast ماهي إلا تغليف لStrstream .... وهذه الأخيرة رغم سهولتها في الإستخدام إلا أنه لدي تحفظ كبير على الأداء لها . فهو كائن مخصص أصلا لتنسيق المخرجات وبالتالي لا يستحب إستخدامه داخل العمليات , ما لم تقوم بطباعة التجهيز للطباعة .

لم أقرأ حقيقة كود lexical_cast من قبل, و لكن قرأت أنه يعتمد على الـ stringstream,

أذكر أني جربت استخدام stringstream ضد lexical_cast و كانت lexical_cast أسرع بأربع مرات تقريباً!

لا أدري ما السبب الحقيقي, و لكن أنا متأكد بأن الـ lexical_cast إن كان يستخدم الـ stringstream فإنه لا يعتمد على الـ buffer الخاص بالـ stream و يحدد حجم التحويل وقت الترجمة,

أما الـ stringstream فإنه يقوم ببناء buffer ثم يقوم بعملية الـ formatting فوقه.

عموماً يمكنك استخدام عمليات الـ formatting فقط دون أن تدع للـ stream حجز الذاكرة, و ربما هذه ما يقوم به الـ lexical_cast,

عن قريب نلقي نظرة على الكود و نعود :)

تحياتي ...

#16
Khaled.Alshaya كتب:
السلام عليكم ....

لم أقرأ حقيقة كود lexical_cast من قبل, و لكن قرأت أنه يعتمد على الـ stringstream,

أذكر أني جربت استخدام stringstream ضد lexical_cast و كانت lexical_cast أسرع بأربع مرات تقريباً!

لا أدري ما السبب الحقيقي, و لكن أنا متأكد بأن الـ lexical_cast إن كان يستخدم الـ stringstream فإنه لا يعتمد على الـ buffer الخاص بالـ stream و يحدد حجم التحويل وقت الترجمة,

أما الـ stringstream فإنه يقوم ببناء buffer ثم يقوم بعملية الـ formatting فوقه.

عموماً يمكنك استخدام عمليات الـ formatting فقط دون أن تدع للـ stream حجز الذاكرة, و ربما هذه ما يقوم به الـ lexical_cast,

عن قريب نلقي نظرة على الكود و نعود :)

تحياتي ...

هو معتمد على strstream أو basic_stringstream , على حسب المايكرو ... ومثل ما قلت فهو يعتمد على الmetaprogramming لتحديد حجم الbuffer فمثلاً الint ليس مثل ال double ...

لكن يظل أنه تغليف لها وبالتالي بطأ العمليات نفسها بعد تحديد حجم الbuffer لا يمكن تجاهله ...

حياك , وفي النهاية هي طريقة ممتازة جداً لكن للأسف الزين ما يكتمل :wink:

#17

يعطيك العافية .

نعم , الرسالة بدت مفهومة نوعاً ما .. خذ مثلاً هذا المثال .. الذي جنّني في أحد السنين الغابرة :D

#include <iostream>

int main()
{
	std::cout << std::wstring(L"wstring")  << std::endl;

	return 0;
}

بتتبع رسال الخطأ .. نجد أن المشكلة تتبيّن ... يوجد كلمة char :) .. والنوع المرر هو wchar_t .. من هنا ..نمسك طرف الخيط .

عموماً , بانتظار موضوع Concepts , رأيتك في أكثر من موضوع تمدحه .. وتثني عليه .. يبدو أنه "لحية غانمة" ,, نريد نتعرّف عليه :D .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

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