[英]Is this defining a lambda function and assigning the function pointer to a value at the same time?
Still many C++ codes are so difficult for me to understand..仍然有很多 C++ 代码对我来说太难理解了..
Below is a code snippet from dlib ( http://dlib.net file : dlib/external/pybind11/include/pybind11/pybind11.h)下面是来自 dlib 的代码片段( http://dlib.net文件:dlib/external/pybind11/include/pybind11/pybind11.h)
It's a member function definition of class cpp_function
and I didn't try to understand the code(no time to do that..that's sad..).它是类
cpp_function
的成员函数定义,我没有试图理解代码(没有时间这样做......这很难过......)。 I can't understand the syntax in the line I put *** this line!
我无法理解我放
*** this line!
的行中的语法*** this line!
comment at below.在下面评论。 I understand the lambda function(unnamed function), so is it assigning a function pointer to
rec->impl
, the function taking function_call &call
as argument and returning handle
?我了解 lambda 函数(未命名函数),所以它是否将函数指针分配给
rec->impl
,该函数以function_call &call
作为参数并返回handle
? So, it looks like defining a function and at the same time assigning the function pointer to a variable.所以,它看起来就像定义一个函数,同时将函数指针分配给一个变量。 Having asked it, it looks so now.. Please someone confirm this.
问了之后,现在看起来是这样..请有人确认这一点。
void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) {
using namespace detail;
struct capture { remove_reference_t<Func> f; };
...
rec->impl = [](function_call &call) -> handle { // <=== *** this line!
cast_in args_converter;
/* Try to cast the function arguments into the C++ domain */
if (!args_converter.load_args(call))
return PYBIND11_TRY_NEXT_OVERLOAD;
/* Invoke call policy pre-call hook */
process_attributes<Extra...>::precall(call);
/* Get a pointer to the capture object */
auto data = (sizeof(capture) <= sizeof(call.func.data)
? &call.func.data : call.func.data[0]);
capture *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));
/* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */
const auto policy = return_value_policy_override<Return>::policy(call.func.policy);
/* Function scope guard -- defaults to the compile-to-nothing `void_type` */
using Guard = extract_guard_t<Extra...>;
/* Perform the function call */
handle result = cast_out::cast(
std::move(args_converter).template call<Return, Guard>(cap->f), policy, call.parent);
/* Invoke call policy post-call hook */
process_attributes<Extra...>::postcall(call, result);
return result;
};
...
using FunctionType = Return (*)(Args...);
constexpr bool is_function_ptr =
std::is_convertible<Func, FunctionType>::value &&
sizeof(capture) == sizeof(void *);
if (is_function_ptr) {
rec->is_stateless = true;
rec->data[1] = const_cast<void *>(reinterpret_cast<const void *>(&typeid(FunctionType)));
}
}
rec->impl = [](function_call &call) -> handle
creates a lambda which takes one argument of type function_call
and returns a handle
, then assigns it to rec->impl
.创建一个 lambda,它接受一个
function_call
类型的function_call
并返回一个handle
,然后将其分配给rec->impl
。
As lambdas are basically unnamed structs, they also have unnamed types.由于 lambda 基本上是未命名的结构,因此它们也具有未命名的类型。 Since
rec->impl
obviously exists already and is thus not templatized on the lambda type, the lambda gets converted to some other type during the assignment.由于
rec->impl
显然已经存在,因此没有在 lambda 类型上进行模板化,因此在赋值期间 lambda 会转换为其他类型。 (Note: there could however be a templatized and overloaded operator=
here) (注意:然而,这里可能有一个模板化和重载的
operator=
)
Typically such types which can take lambdas are either std::function
or function pointers as stateless lambdas can be converted to function pointers.通常,可以采用 lambda 的此类类型是
std::function
或函数指针,因为无状态 lambda 可以转换为函数指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.