سؤال

لدي قالب متابع محدد حتى أتمكن

/// cast using implicit conversions only
template <class To,class From>
inline To safe_cast( const From &from ) {return from;}

في كثير من الأحيان (على سبيل المثال ، عند تمرير الوسائط إلى sprintf ووظائف مماثلة) ، أود استخدام هذا القالب لإجراء تحويل من فئة سلسلة إلى سلسلة على غرار C. ومع ذلك ، فإنه يدل على أن هذا غير ممكن عندما يتم تمرير مؤقت ، لأن المؤقتة لن تعيش لفترة كافية.

النظر في المثال التالي:

class Object
{
  public:
  MyStringClass GetDebugName() const;
};

Object obj;
printf("%s",safe_cast<const char *>(obj.GetDebugName()));

يعيش المؤشر المؤقت من OBJ.GetDebugName () فقط أثناء SAFE_CAST والمؤشر غير صالح (يشير إلى بيانات السلسلة المؤقتة التي تم تدميرها بالفعل) عند داخل printf.

بصفتي حلًا ، أستخدم حاليًا لعبة Direct Direct بدون استدعاء قالب: const char *c = (const char *)(obj.GetDebugName(), ، ولكن هذا له عيب في انخفاض السلامة من النوع ، حيث أن فريق الممثلين قوي بشكل غير ضروري (على سبيل المثال ، سينجح بصمت حتى لو كان OBJ.GetDebugName () سيعود ENT بدلاً من قيمة السلسلة). static_cast قد يكون أفضل قليلاً ، ولكن حتى هذا قوي للغاية ، أود أن أحصل على خطأ في أي موقف يكون فيه المصبوب غير متأكد من أن يكون آمنًا.

1) إذا لم أكن مخطئًا ، فإن المعيار يقول إن وقت الحياة المؤقت هو بيان (ما لم يتم تمديده من خلال الالتزام بمرجع const ، وفي هذه الحالة يكون وقت حياة المرجع). عند النظر إلى مثال printf أعلاه ، لست متأكدًا تمامًا من ماهية "البيان" ، وإذا كان السلوك الذي رأيته مطابقًا أم لا. إذا كان البيان هو printf بأكمله ، فإن عمر const from & from أقصر - ما هو العمر الذي يجب أن أتوقعه من المؤقتة؟ هل يمكن لأحد أن يوضح؟

2) هل هناك طريقة أخرى لإجراء تحويل سيكون آمنًا ، لكن النتيجة ستعيش لفترة كافية لتكون مفيدة؟

يحرر:

من فضلك ، فكر في هذا النوع من الأسئلة العامة ، أنا أسعى للحصول على آلية كيف يمكن للتحويل مثل هذا القيام به فيما يتعلق مدى الحياة المؤقتة ، لست مهتمًا جدًا بحالة خاصة لأي فئة سلسلة معينة.

لتوضيح لماذا لا أرغب في استخدام .c_str أو وظيفة عضو مماثلة: أود أن يكون رمز التحويل هو نوع الملاحق ، لا أريد أن يعتمد الرمز على حقيقة أنني أعرف أن نوع السلسلة المحدد قد تم تنفيذه C_STR ، أنا تريد أن تعمل حتى إذا تم إرجاع فئة سلسلة مختلفة بواسطة ObjectDebugName ، أو حتى إذا كان ObjectDebugName سيعيد بالفعل const char * (الذي يستبعد إمكانية الاتصال.

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

المحلول

يمكنني إجراء مجموعة صريحة ولكنها آمنة

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

1) إذا لم أكن مخطئًا ، فإن المعيار يقول إن وقت الحياة المؤقت هو بيان (ما لم يتم تمديده من خلال الالتزام بمرجع const ، وفي هذه الحالة يكون وقت حياة المرجع). عند النظر إلى مثال printf أعلاه ، لست متأكدًا تمامًا من ماهية "البيان" ، وإذا كان السلوك الذي رأيته مطابقًا أم لا. إذا كان البيان هو printf بأكمله ، فإن عمر const from & from أقصر - ما هو العمر الذي يجب أن أتوقعه من المؤقتة؟ هل يمكن لأحد أن يوضح؟

أنت محق ، يتم تدمير المؤقتة بعد، بعدما printf قد عاد. الرمز الذي قدمته يجب أن يعمل. إذا لم يحدث ذلك ، فهذا يعني أنك قد سددت بعض المعلومات المهمة.

نصائح أخرى

لا أعرف لماذا تستخدم فئة السلسلة الخاصة بك هنا. هل لدى الفصل وظيفة عضو للحصول على const char * منه؟

std :: string getDebugName () ؛

printf ("٪ s" ، getDebugName (). c_str ()) ؛

سيكون آمنًا لأن المؤقتة ستبقى صالحة خلال هذا البيان ، على سبيل المثال.

يمكنك استدعاء وظيفة التحويل مباشرة:

printf("%s", obj.GetDebugName().operator const char*());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top