如何正确检查 std::function 在 C++11 中是否为空
How to properly check if std::function is empty in C++11?
我想知道如何正确检查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 不是空的。
条形图为空。
- MSVC是否支持C++11样式的属性而不是__declspec
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 如何检测VS C++编译器是否支持C++11?
- C++ 11 中的锁定是否保证访问数据的新鲜度?
- 是否可以使用 DirectX 3D 11 绘制由三角形组成的圆?
- C++11 标准是否保证零值有符号整数的一元减号为零?
- C++11:16 字节原子<>变量是否在 16 字节边界上自动对齐,从而允许CMPXCHG16B指令?
- 是否可以仅使用标准 c++/c++11 实现不带"sleep"的计时器?
- 目标c是否需要一个标准来定义像c++11这样的内存模型
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- 是否可以通过使用移动/交换 c++11 来延长返回的临时变量的生命周期
- 是否可以在 64 位系统中为 11 位系统中的图形创建位邻接数组
- 当加入 C++11 函数的线程仍未终止时,是否可以返回?
- 此包络实现是否正确使用 C++11 原子学
- C++11: Atomic::compare_exchange_weak 是否支持非基元类型?
- 如果没有带有函数签名的 rvalue 参数,是否会执行 C++ 11 中的移动语义?
- 假设 C++11 中已知子级布局,重新插入基类是否安全
- C++11 中是否有实际的 4 位整数数据类型
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 如何优雅地检查模板类型是否来自C 11中的特定基类