Boost 1.55,MSVC Express 2012。
Tribool表达评估错误。
仅当我明确指定tribool(false)时,它才能正常工作。

故事的寓意:编译器根据VALUES选择TYPES。

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

输出:
  • indet:1吗?不确定:false
  • indet:0?不确定:false
  • 是:1?不确定:true
  • true:0?不确定:true
  • indet:1吗?不确定:tribool(false)
  • false:0?不确定:tribool(false)
  • indet:1吗?不确定:tribool(true)
  • true:0?不确定:tribool(true)

  • 源代码:
    #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应该正确地为此警告您。从他们自己的documentation:

     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.
    

    Because your ternary operator doesn't return the same type, for the combination of bool and indeterminate, the result undergoes a conversion which probably matches the

         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.
    

    Which matches the,

    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 );
    ...
    

    关于c++ - C++ Boost Tribool三元运算符错误值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21061745/

    10-11 19:02