I am learning C++ recently and I noticed an example on cppreference, part of which goes like this:
struct B
{
explicit B(int) { }
explicit operator bool() const { return true; }
};
int main()
{
B b2(2); // OK: direct-initialization selects B::B(int)
if (b2) ; // OK: B::operator bool()
}
The introduction to implicit conversions tells me "when the expression is used in an if statement or a loop" the result of this expression( b2 ) will be converted into bool
type implicitly.
Also, the introduction to explicit specifier tells me if "a conversion function is explicit, it cannot be used for implicit conversions".
Since b2 will be converted implicitly in if(b2)
, and the conversion function is explicit
, how comes if(b2)
is ok?
Explicit Keyword in C++ is used to mark constructors to not implicitly convert types in C++. It is optional for constructors that take exactly one argument and work on constructors(with a single argument) since those are the only constructors that can be used in typecasting.
Implicit conversions allow the compiler to treat values of a type as values of another type. There's at least one set of scenarios in which this is unambiguously bad: non-total conversions. That is, converting an A to a B when there exists A s for which this conversion is impossible.
An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.
Contextual conversion is special; since C++11, explicit
conversion functions will be considered in contextual conversions.
(emphasis mine)
(since C++11)
In the following contexts, the type
bool
is expected and the implicit conversion is performed if the declarationbool t(e);
is well-formed (that is, an explicit conversion function such as explicit T::operator bool() const; is considered). Such expression e is said to be contextually converted to bool.
- the controlling expression of if, while, for;
- the operands of the built-in logical operators !, && and ||;
- the first operand of the conditional operator ?:;
- the predicate in a static_assert declaration;
- the expression in a noexcept specifier;
- the expression in an explicit specifier; (since C++20)
- the predicate of a contract attribute. (since C++20)
That means for if (b2)
, b2
will be converted to bool
implicitly by B::operator bool()
even it's declared as explicit
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With