Boost 1.55,MSVC Express 2012。 与摩托教池的表达式评估错误。 只有在明确指定TRIBOOL(FALSE)时才能正确工作。

故事的寓意:编译器根据值选择类型。

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

输出:

  1. indet:1?不确定:假
  2. indet:0?不确定:假
  3. 是的:1?不确定:真正的
  4. 是的:0?不确定:真正的
  5. indet:1?不确定:TRIBOOL(假)
  6. 假:0?不确定:TRIBOOL(假)
  7. indet:1?不确定:TRIBOOL(TRUE)
  8. 是的:0?不确定:TRIBOOL(TRUE)
  9. 源代码:

    #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.
.

因为您的三元运算符不会返回相同类型,因为BOOL的组合和不确定,结果经历了可能与

匹配的转换
     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 。它是“评估”的函数指针而不是世代odicetagcode值。

所以,必须使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