Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

explicit specifier doesn't seem to work when converting an object to bool

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?

like image 734
Jinlong Chen Avatar asked Jan 29 '19 15:01

Jinlong Chen


People also ask

What is explicit in c++?

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.

Why is implicit type conversion bad?

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.

What is an implicit conversion?

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.


1 Answers

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 declaration bool 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.

like image 133
songyuanyao Avatar answered Oct 13 '22 00:10

songyuanyao