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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21806632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:49:27  来源:igfitidea点击:

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

c++c++11std-function

提问by NightElfik

I was wondering how to properly check if an std::functionis empty. Consider this example:

我想知道如何正确检查 anstd::function是否为空。考虑这个例子:

class Test {
    std::function<void(int a)> eventFunc;

    void registerEvent(std::function<void(int a)> e) {
        eventFunc = e;
    }

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

This code compiles just fine in MSVC but if I call doSomething()without initializing the eventFuncthe code obviously crashes. That's expected but I was wondering what is the value of the eventFunc? The debugger says 'empty'. So I fixed that using simple if statement:

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

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

This works but I am still wondering what is the value of non-initialized std::function? I would like to write if (eventFunc != nullptr)but std::functionis (obviously) not a pointer.

这有效,但我仍然想知道 non-initialized 的值是std::function什么?我想写,if (eventFunc != nullptr)std::function(显然)不是指针。

Why the pure if works? What's the magic behind it? And, is it the correct way how to check it?

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

回答by Praetorian

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

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

Besides, the notion of an empty lambdadoesn'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?

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



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

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

回答by Dawid Drozd

Check here http://www.cplusplus.com/reference/functional/function/operator_bool/

在这里检查http://www.cplusplus.com/reference/functional/function/operator_bool/

Example

例子

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

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

  foo.swap(bar);

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

  return 0;
}

Output

输出

foo is not callable.

bar is callable.

foo 不可调用。

酒吧是可调用的。

回答by zwcloud

(Let me provide a clear answer.)

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

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

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

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

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

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.

foo 不为空。
酒吧是空的。