1

I am pretty surprised that this struct, which is only explicitly convertible to bool, works fine inside a if statement:

struct A
{
    explicit operator bool(  ) const
    {
        return m_i % 2 == 0;
    }

    int m_i;
};

int main()
{
    A a{ 10 };

    if ( a ) // this is considered explicit
    {
        bool b = a; // this is considered implicit 
                    // and therefore does not compile           
    }        
    return 0;
}

Why is it so? What is the design reason behind it in the C++ Standard? I personally find more explicit the second conversion than the first one. To make it even more clear, I would have expected the compiler forcing to have the following for both the cases:

int main()
{
    A a{ 10 };

    if ( (bool)a )
    {
        bool b = (bool)a;
    }        
    return 0;
}
nyarlathotep108
  • 5,275
  • 2
  • 26
  • 64
  • Yes, inside `if` is like an explicit conversion to bool. (You can't be more explicit than using `if` to convert to `bool`!). http://en.cppreference.com/w/cpp/language/explicit – alfC Sep 19 '17 at 09:42

1 Answers1

2

§6.4 Selection statements [stmt.select]

  1. The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch;

§4 Standard conversions [conv]

Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (8.5).

So the expression of the condition in if must be contextually convertible to bool, which means that explicit conversions are allowed.

This is mode most likely done because the condition of if can only evaluate to a boolean value, so by saying if(cond) you are explicitly stating you want cond to be evaluated to a boolean value.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Thanks, I never heard about the concept of *contextually convertible* before. Can you please add to your answer in which cases is a conversion operation assumed to be contextual? – nyarlathotep108 Sep 19 '17 at 10:04
  • 1
    @nyarlathotep108 as the condition of an `if` `while` `for` statement. Other than that I would have to scan the entire standard. And is beyond the scope of the question. – bolov Sep 19 '17 at 10:06
  • 2
    @nyarlathotep108 found at a quick scan: the operand of logical negation operator (`!op`), operands of logical operators (e.g. `op1 && op2`), of conditional operator `? :`, the assert on a `static_assert`, no except specificator. – bolov Sep 19 '17 at 10:13