【问题标题】:Is this defining a lambda function and assigning the function pointer to a value at the same time?这是在定义一个 lambda 函数并同时将函数指针分配给一个值吗?
【发布时间】: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-&gt;impl

标签: c++ c++11 lambda


【解决方案1】:

rec-&gt;impl = [](function_call &amp;call) -&gt; handle

创建一个 lambda,它接受一个 function_call 类型的参数并返回一个 handle,然后将其分配给 rec-&gt;impl

由于 lambda 基本上是未命名的结构,它们也有未命名的类型。由于rec-&gt;impl 显然已经存在,因此没有在 lambda 类型上进行模板化,因此 lambda 在分配期间被转换为其他类型。 (注意:这里可能存在模板化和重载的operator=

通常可以采用 lambda 的此类类型是 std::function 或函数指针,因为无状态 lambda 可以转换为函数指针。

【讨论】:

    猜你喜欢
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2015-05-09
    • 2020-01-12
    • 2023-03-13
    • 1970-01-01
    • 2013-10-08
    相关资源
    最近更新 更多