【发布时间】:2021-01-27 13:27:13
【问题描述】:
仍然有很多 C++ 代码对我来说很难理解..
下面是来自 dlib 的代码 sn-p(http://dlib.net 文件:dlib/external/pybind11/include/pybind11/pybind11.h)
这是cpp_function 类的成员函数定义,我没有尝试理解代码(没有时间这样做.. 很伤心..)。我无法理解我在下面添加*** this line! 注释的行中的语法。我了解 lambda 函数(未命名函数),那么它是否将函数指针分配给 rec->impl,该函数以 function_call &call 作为参数并返回 handle?因此,它看起来就像定义一个函数,同时将函数指针分配给一个变量。问过了,现在看起来是这样。请有人确认一下。
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)));
}
}
【问题讨论】:
-
第一个lambda函数被创建,lambda函数的创建结果是
std::function类型的对象,你可以认为这个类型是一个重函数指针(加上额外的闭包数据)。所以这个创建的对象被分配给变量rec->impl。