Why std::function does not implicitly convert to b

2019-04-11 02:49发布

问题:

This question already has an answer here:

  • No viable conversion from std::function to bool 1 answer

Consider the following code.

#include <functional>

int main(void)
{
    std::function<void()> f1;
    if (f1) { /* ok */
        ...
    }

    bool b = f1; /* compile-error */
    bool B = !f1; /* ok */
    ...
}

std::function<> converts implicitly to bool in some circumstances but not in all of them. Assigning it to a bool-variable does not work, whereas the result of an operation or using it in an if()-statement is OK.

Why is that so? It seems we have to do an boolean-operation on it, then the conversion works.

What I did to make work the b = f1-line is the good ol' double bang: !!. It looks like an antique in such modern C++-code.

EDIT: This compiles as well:

bool b = f1 || f1; /* OK */

回答1:

Note that std::function::operator bool is explicit conversion function, implicit conversion is not allowed. So bool b = f1; won't work. (Explicit conversion will work well if you use static_cast like bool b = static_cast<bool>(f1);.)

using it in an if()-statement is OK.

When being used with if, operator! or operator||, contextual conversions will take effect, and the explicit conversion function will be considered.

(since C++11)

In the following five contexts, the type bool is expected and the implicit conversion sequence is built if the declaration bool t(e); is well-formed. that is, the explicit user-defined conversion function such as explicit T::operator bool() const; is considered. Such expression e is said to be contextually convertible to bool.

  • controlling expression of if, while, for;
  • the logical operators !, && and ||;
  • the conditional operator ?:;
  • static_assert;
  • noexcept.