如何正确检查 std::function 在 C++11 中是否为空

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

本文关键字:是否 C++11 function 何正确 检查 std      更新时间:2023-10-16

我想知道如何正确检查std::function是否为空。请考虑以下示例:

class Test {
    std::function<void(int a)> eventFunc;
    void registerEvent(std::function<void(int a)> e) {
        eventFunc = e;
    }
    void doSomething() {
        ...
        eventFunc(42);
    }
};

这段代码在 MSVC 中编译得很好,但是如果我调用doSomething()而不初始化eventFunc代码显然会崩溃。这是意料之中的,但我想知道eventFunc的价值是什么?调试器说'empty' 。所以我使用简单的 if 语句修复了这个问题:

   void doSomething() {
        ...
        if (eventFunc) {
            eventFunc(42);
        }
   }

这有效,但我仍然想知道非初始化std::function的值是什么?我想写if (eventFunc != nullptr)std::function(显然)不是一个指针。

为什么纯 if 有效?它背后的魔力是什么?而且,这是如何检查它的正确方法吗?

您不是在检查空的 lambda,而是在检查std::function中是否存储了可调用的目标。检查是明确定义的,并且由于std::function::operator bool允许在需要布尔值的上下文(例如 if 语句中的条件表达式)中隐式转换为 bool

此外,空 lambda 的概念并没有真正的意义。在后台,编译器将 lambda 表达式转换为 struct(或class)定义,您捕获的变量存储为此struct的数据成员。还定义了公共函数调用运算符,它允许您调用 lambda。那么空的λ是什么呢?


如果您愿意,您也可以编写if(eventFunc != nullptr),它相当于您在问题中的代码。 std::function定义了operator==operator!=重载,以便与nullptr_t进行比较。

在这里查看 std::function::operator bool

返回值

  • 如果对象可调用,则为 true。
  • 否则为 false(对象为空函数)。
<小时 />

示例

// 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
}
<小时 />

输出

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

(让我提供一个明确的答案。

您可以使用 std::function::operator bool 检查std::function是否为空。

true:如果对象是可调用的。
false:否则(对象为空函数)

#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;
}

输出

Foo 不是空的。
条形图为空。