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

Nig*_*fik 87 c++ c++11 std-function

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

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

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

    void doSomething() {
        ...
        eventFunc(42);
    }
};
Run Code Online (Sandbox Code Playgroud)

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

   void doSomething() {
        ...
        if (eventFunc) {
            eventFunc(42);
        }
   }
Run Code Online (Sandbox Code Playgroud)

这有效,但我仍然想知道非初始化的价值是std::function多少?我想写,if (eventFunc != nullptr)std::function(显然)不是指针.

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

Pra*_*ian 92

你没有检查一个空的lambda,但是它是否std::function有一个可调用的目标.检查是明确定义的,因为std::function::operator bool它允许bool在需要布尔值的上下文中隐式转换(例如if语句中的条件表达式).

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


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

  • @Praetorian我想说的是,标准为短语"隐式转换"赋予了一个非常具体的含义,它与"对bool的语境转换"明显不同,后者也具有非常特殊的含义.这里没有"Is-a"关系.我知道初学者可能不需要立即知道隐式/显式/上下文转换之间的区别,但最好是在潜意识中学习正确的单词,而不是在以后打破旧的习惯. (5认同)
  • @KyleStrand是的,与`nullptr`相比也会有效,`if(eventFunc!= nullptr)`相当于上面问题中的`if(eventFunc)`. (3认同)
  • 从技术上讲,`std :: function :: operator bool`不允许隐式转换为`bool`.毕竟它被标记为`explicit`,但是标准对某些期望布尔表达式的语言结构做了一个例外,称它为"上下文转换为bool".你可以在这里找到相关的标准片段和解释:http://chris-sharpe.blogspot.com/2013/07/contextually-converted-to-bool.html (2认同)
  • @bcrist 是的,我知道布尔转换运算符是“显式”的,这就是为什么我小心地声明*允许在需要布尔值的上下文中隐式转换为“bool”*。这正是相关代码中发生的情况。 (2认同)

Daw*_*ozd 20

点击这里http://www.cplusplus.com/reference/functional/function/operator_bool/

// 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;
}
Run Code Online (Sandbox Code Playgroud)

产量

foo不可调用.

酒吧是可以赎回的.

  • 我认为没有`swap()`这个答案会更清楚.我以为输出是倒退的,直到我意识到它. (24认同)

zwc*_*oud 7

(让我给出一个明确的答案。)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

输出

foo 不为空。
酒吧是空的。

  • 您的结果字符串已交换。 (2认同)