Question

Boost 1.55, MSVC express 2012.Mauvaise évaluation d’expression avec tribool.Cela ne fonctionne correctement que lorsque je spécifie explicitement tribool(false).

Morale de l'histoire:le compilateur choisit les TYPES en fonction des VALEURS.

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

Sortir:

  1. indet :1?indéterminé :FAUX
  2. indet :0 ?indéterminé :FAUX
  3. vrai :1?indéterminé :vrai
  4. vrai :0 ?indéterminé :vrai
  5. indet :1?indéterminé :tribool(faux)
  6. FAUX :0 ?indéterminé :tribool(faux)
  7. indet :1?indéterminé :tribool (vrai)
  8. vrai :0 ?indéterminé :tribool (vrai)

Code source:

#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;
}
Était-ce utile?

La solution

Il s'agit de différents types et MSVC devrait à juste titre vous avertir à ce sujet ;de leur propre 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.

Parce que votre opérateur ternaire ne renvoie pas le même type, pour la combinaison de bool et indeterminate, le résultat subit une conversion qui correspond probablement au

     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.

Ce qui correspond au,

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

définition dans tribool.hpp.C'est ce pointeur de fonction qui est "évalué" au lieu du false valeur.

Donc, vous devez avoir le ? L'opérateur renvoie le même type.Modifiez vos macros pour qu'elles ressemblent à ceci :

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

Ou bien,

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 );
...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top