Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly check if std::function is empty in C++11?

You're not checking for an empty lambda, but whether the std::function has a callable target stored in it. The check is well-defined and works because of std::function::operator bool which allows for implicit conversion to bool in contexts where boolean values are required (such as the conditional expression in an if statement).

Besides, the notion of an empty lambda doesn't really make sense. Behind the scenes the compiler converts a lambda expression into a struct (or class) definition, with the variables you capture stored as data members of this struct. A public function call operator is also defined, which is what allows you to invoke the lambda. So what would an empty lambda be?


You can also write if(eventFunc != nullptr) if you wish to, it's equivalent to the code you have in the question. std::function defines operator== and operator!= overloads for comparing with a nullptr_t.


Check here for std::function::operator bool

Return value

  • true if the object is callable.
  • false otherwise (the object is an empty function).

Example Play with it online

// function::operator bool example
#include <iostream>     // std::cout
#include <functional>   // std::function, std::plus

int main ()
{
    std::function<int(int,int)> foo; // empty
    
    if(foo)
    {
        std::cout << "[1] foo is NOT empty" << std::endl;
    }
    else
    {
        std::cout << "[1] foo is EMPTY" << std::endl;
    }
    
    // Now we can assign example
    foo = std::plus<int>();
  
    if(foo)
    {
        std::cout << "[2] foo is NOT empty" << std::endl;
    }
    else
    {
        std::cout << "[2] foo is EMPTY" << std::endl;
    }
  
    // Example use with ternary operator (https://www.cprogramming.com/reference/operators/ternary-operator.html)
    std::cout << "[3] foo is " << (foo ? "callable" : "NOT callable") << std::endl;
    
    // make it empty
    foo = {};
    std::cout << "[4] foo is " << (foo ? "callable" : "NOT callable") << std::endl;
    
    foo = [](int a, int b){ return a+b; };
    std::cout << "[5] foo is " << (foo ? "callable" : "NOT callable") << std::endl;
    
    return foo(1, 1) == 2; // return 1
}

Output

[1] foo is EMPTY
[2] foo is NOT empty
[3] foo is callable
[4] foo is NOT callable
[5] foo is callable

(Let me provide a clear answer.)

You can check if a std::function is empty with std::function::operator bool.

true: if the object is callable.
false: otherwise (the object is an empty function)

Example

#include <iostream>
#include <functional>

int main ()
{
    std::function<int(int,int)> foo = std::plus<int>();//assigned: not empty
    std::function<int(int,int)> bar;//not assigned: empty

    std::cout << "foo is " << (foo ? "not empty" : "empty") << ".\n";
    std::cout << "bar is " << (bar ? "not empty" : "empty") << ".\n";

    return 0;
}

Output

foo is not empty.
bar is empty.