سؤال

دفعة 1.55، MSVC اكسبرس 2012.تقييم التعبير الخاطئ مع tribool.إنه يعمل بشكل صحيح فقط عندما أحدد tribool(false) بشكل صريح.

المغزى من القصة:يختار المترجم الأنواع بناءً على القيم.

auto a = 0? indeterminate : false; // type function pointer
auto b = 0? indeterminate : true; // type bool

انتاج:

  1. إندت :1؟غير محدد :خطأ شنيع
  2. إندت :0؟غير محدد :خطأ شنيع
  3. حقيقي :1؟غير محدد :حقيقي
  4. حقيقي :0؟غير محدد :حقيقي
  5. إندت :1؟غير محدد :تريبول (خطأ)
  6. خطأ شنيع :0؟غير محدد :تريبول (خطأ)
  7. إندت :1؟غير محدد :تريبول (صحيح)
  8. حقيقي :0؟غير محدد :تريبول (صحيح)

مصدر الرمز:

#include <iostream>
#include <boost/logic/tribool.hpp>

using namespace boost;

void test_tribool( const tribool& v, const char* name )
{
    const char* s;
    if ( v )
        s = "true";
    else if ( !v )
        s = "false";
    else
        s = "indet";
    std::cout << s << "\t: " << name << std::endl;
}

#define TEST_TRIBOOL( ... ) test_tribool( (__VA_ARGS__), #__VA_ARGS__ );

int main(int argc, char** argv)
{
    TEST_TRIBOOL( 1? indeterminate : false );
    TEST_TRIBOOL( 0? indeterminate : false );

    // warning C4305: ':' : truncation from 'bool (__cdecl *)(boost::logic::tribool,boost::logic::detail::indeterminate_t)' to 'bool'
    TEST_TRIBOOL( 1? indeterminate : true );

    // warning C4305: ':' : truncation from 'bool (__cdecl *)(boost::logic::tribool,boost::logic::detail::indeterminate_t)' to 'bool'
    TEST_TRIBOOL( 0? indeterminate : true );


    TEST_TRIBOOL( 1? indeterminate : tribool(false) );
    TEST_TRIBOOL( 0? indeterminate : tribool(false) );
    TEST_TRIBOOL( 1? indeterminate : tribool(true) );
    TEST_TRIBOOL( 0? indeterminate : tribool(true) );

    return 0;
}
هل كانت مفيدة؟

المحلول

هذه أنواع مختلفة ويجب على MSVC أن يعطيك تحذيرًا بشأن هذا الأمر؛من تلقاء نفسها توثيق:

 The following rules apply to the second and third expressions:

     If both expressions are of the same type, the result is of that type.

     If both expressions are of arithmetic or enumeration types, 
     the usual arithmetic conversions (covered in Arithmetic Conversions)
     are performed to convert them to a common type.

     If both expressions are of pointer types or if one is a pointer type 
     and the other is a constant expression that evaluates to 0,
     pointer conversions are performed to convert them to a common type.

     If both expressions are of reference types, reference conversions 
     are performed to convert them to a common type.

     If both expressions are of type void, the common type is type void.

     If both expressions are of a given class type, the common type is 
     that class type.

 Any combinations of second and third operands not in the preceding
 list are illegal. The type of the result is the common type, and it is
 an l-value if both the second and third operands are of the same type
 and both are l-values.

نظرًا لأن عامل التشغيل الثلاثي الخاص بك لا يُرجع نفس النوع، فبالنسبة لمجموعة منطقية وغير محددة، تخضع النتيجة لتحويل ربما يطابق

     If both expressions are of pointer types or if one is a pointer type 
     and the other is a constant expression that evaluates to 0,
     pointer conversions are performed to convert them to a common type.

الذي يطابق،

typedef bool (*indeterminate_keyword_t)(tribool, detail::indeterminate_t);

التعريف في tribool.hpp.إنه مؤشر الوظيفة الذي يتم "تقييمه" بدلاً من مؤشر الوظيفة false قيمة.

لذلك، يجب أن يكون لديك ? يقوم المشغل بإرجاع نفس النوع.قم بتغيير وحدات الماكرو الخاصة بك لتبدو كما يلي:

TEST_TRIBOOL( 1 ? tribool(indeterminate) : tribool(false));

أو بدلا من ذلك،

const tribool t_indet(indeterminate);
const tribool t_false(false);
const tribool t_true(true);

TEST_TRIBOOL( 1 ? t_indet : t_false );
TEST_TRIBOOL( 0 ? t_indet : t_false );
...
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top