مقارنة عنوان STD :: endl
-
22-09-2019 - |
سؤال
أنا أفحص جزءًا من الكود الحالي واكتشف أنه يتصرف بشكل مختلف عند تجميعه باستخدام C ++ 9 و Mingw:
inline LogMsg& LogMsg::operator<<(std::ostream& (*p_manip)(std::ostream&) )
{
if ( p_manip == static_cast< std::ostream& (*)(std::ostream&) > ( &std::endl<char, std::char_traits<char> >) )
{
msg(m_output.str());
m_output.str( "" );
}
else
{
(*p_manip) (m_output); // or // output << p_manip;
}
return *this;
}
كما يوحي الاسم ، هذه فئة سجل وتزداد حجمها operator<<()
لتجريد endls من التيار.
اكتشفت لماذا يتصرف بشكل مختلف: الاختبار p_manip == static_cast...
ينجح مع Mingw بينما يفشل مع Visual C ++ 9.
- Mingw "يتجاهل" الممثلين ويعيد العنوان الحقيقي
std::endl
; - Visual C ++ 9 يلقي في الواقع المؤشر إلى الانحناء ويعيد عنوانًا مختلفًا.
لقد غيرت الاختبار إلى if ( p_manip == std::endl )
والآن يتصرف كما هو متوقع.
سؤالي هو: ما هو الاختبار المنطقي وراء هذا الاختبار المعقد (وفي الواقع ، الخطأ)؟
من أجل الانتهاء:
class LogStream
{
public:
LogStream() {}
protected:
std::ostringstream m_output;
};
class LogMsg : public LogStream
{
friend LogMsg& msg() ;
static LogMsg s_stream;
public:
LogMsg() {}
template <typename T>
inline LogMsg& operator<<(T p_data);
inline LogMsg& operator<<(std::ostream& (*p_manip)(std::ostream&) );
};
المحلول 2
للحصول على معلومات:
البيان if ( p_manip == std::endl )
لا يتم تجميعه على المترجم الأصلي (GCC 3.4.5 ، المترجم الذي تم تطوير الكود عليه في الأصل).
هذا يعني أن الاختبار لم يكن خطأ كما ذكرت في سؤالي.
نصائح أخرى
في تخمين ، أقول إن المؤلف الأصلي لم يدرك أنهم كانوا أنواعًا متوافقة ، وقاموا بالتحويل على المواصفات (بدون مطالبة المترجم بذلك).