这是它完美工作的方式:
#include <iostream>
#include <functional>
void qwer(std::function<void()> &x)
{
x();
}
void e()
{
std::cout << "hello" << std::endl;
}
int main()
{
//void (*ee)() = e;
std::function<void()> ee = e;
qwer(ee);
}
但它不是这样的:
#include <iostream>
#include <functional>
void qwer(std::function<void()> &x)
{
x();
}
void e()
{
std::cout << "hello" << std::endl;
}
int main()
{
void (*ee)() = e;
//std::function<void()> ee = e;
qwer(ee);
}
问题:
test2.cpp:18:7: error: cannot bind non-const lvalue reference of type ‘std::function<void()>&’ to an rvalue of type ‘std::function<void()>’
18 | qwer(ee);
| ^~
In file included from /usr/include/c++/9/functional:59,
from test2.cpp:2:
/usr/include/c++/9/bits/std_function.h:667:7: note: after user-defined conversion: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = void (*)(); <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = void; _ArgTypes = {}]’
667 | function<_Res(_ArgTypes...)>::
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.cpp:4:34: note: initializing argument 1 of ‘void qwer(std::function<void()>&)’
4 | void qwer(std::function<void()> &x)
| ~~~~~~~~~~~~~~~~~~~~~~~^
他为什么写ee
它是rvalue
什么?毕竟,事实并非如此。
在第一种情况下,函数的形式参数和实际参数的类型与引用值一致。那些。该函数接受
std::function<void()>&
,并将一个类型的实例传递给它std::function<void()>
。在更一般的情况下,T&
分别T
。显然,这样的绑定是允许的,例如,这通常用于修改传递给函数的变量。在第二种情况下,变量的类型(函数指针)与它不同
std::function<void()>
但可以转换为它。在这种情况下,为了确保函数的调用,创建了一个临时变量类型std::function<void()>
。int
(对于基本类型,我们可以用and举个例子double
,其中整数变量可以隐式转换为实数。)这一次,为了使绑定适用于正式类型,必须添加 const (因为语言禁止绑定非常量引用的临时对象)或应该删除该引用。在这种情况下,变量只生成“右值”(您可以在此处ee
阅读有关表达式类别的更多信息),即 一个临时的未命名变量,预计将绑定到正式参数。x
回到基本类型,我们可以考虑以下选项: