§5.14/1
The
&&
operator groups left-to-right. The operands are both contextually converted to typebool
(Clause 4)... Unlike&
,&&
guarantees left-to-right evaluation: the second operand is not evaluated if the first operand isfalse
.
§4/2
[Note: expressions with a given type will be implicitly converted to other types in several contexts:
— When used as operands of operators. The operator’s requirements for its operands dictate the destination type (Clause 5).
...
This is about as clear as the standard gets. First var1
will be implicitly converted to bool
, and then, if it is true
, var2
will be implicitly converted to bool
.
Edit: I'll quote also §4.12/1
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type
bool
. A zero value, null pointer value, or null member pointer value is converted tofalse
; any other value is converted totrue
. A prvalue of typestd::nullptr_t
can be converted to a prvalue of typebool
; the resulting value isfalse
.
Edit 2: For some arbitrary type T
, see §4/3,
... 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 tobool
and is well-formed if and only if the declarationbool t(e);
is well-formed, for some invented temporary variablet
(8.5).
For the meaning of this initialization, see §8.5/16
— Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered. The applicable conversion functions are enumerated (13.3.1.5), and the best one is chosen through overload resolution (13.3). The user-defined conversion so selected is called to convert the initializer expression into the object being initialized. If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
There is even more detail in §13.3.1.5 and §13.3, but you will be reading all night and then some. But the bottom line is that if T
is a class type, then there has to be a conversion function. The best practice would be to define explicit operator bool
for the class. However you could also do something like operator void*
, which is what std::ios
and its derived classes define, because void*
can then be converted to bool
in a standard conversion sequence. (This should be regarded as a deprecated idiom in C++11.)