문제

Boost 1.55, MSVC Express 2012. Tribool과의 잘못된 표현 평가. 리포토 (거짓)를 명시 적으로 지정할 때만 올바르게 작동합니다.

이야기의 도덕 : 컴파일러는 값을 기반으로 유형을 선택합니다.

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

출력 :

  1. Indet : 1?불확정 : 거짓
  2. Indet : 0?불확정 : 거짓
  3. true : 1?불확실성 : 사실
  4. true : 0?불확실성 : 사실
  5. Indet : 1?불확실성 : Tribool (거짓)
  6. false : 0?불확실성 : Tribool (거짓)
  7. Indet : 1?불확실성 : Tribool (true)
  8. true : 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.
.

Ternary 연산자가 동일한 유형을 반환하지 않기 때문에 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 .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