繁体   English   中英

您应该在 std::function 旁边使用 std::unique_ptr 吗?

[英]Should you use std::unique_ptr alongside std::function?

我无法找出处理std::function分配和释放的最佳方法。

当然,底层的 function 永远不会被释放,但是捕获的变量等需要被释放。

我认为这是在std::function的析构函数中释放的。

这是否意味着管理持久函数的最佳方法是使用std::unique_ptr<std::function<...>>std::shared_ptr<std::function<...>> ,甚至只是一个原始指针std::function<...>*

这不是一个额外的间接指针吗? 这是 go 的推荐方法吗?

请记住, std::function不是 lambda。 std::function没有捕获。 它是围绕 function 的多态包装器,例如 object,例如 lambda。

std::function的(非常粗略、不完整和不正确的)表示如下所示:

template<typename R, typename... Args>
struct function {
    function(auto lambda) :
        fptr{[](void* l, Args...){ static_cast<decltype(lambda)>(l)(std::forward<Args>(args)...); }}
        function_object{new auto(lambda)} {}
    
    auto operator()(Args...) const -> R {
        return fptr(function_object, std::forward<Args>(args)...);
    }

    // other members...

private:
    R(*fptr)(void*, Args...);
    void* function_object;
};

如您所见, function_object成员是动态分配的。 这是 lambda,lambda 包含捕获。 只有在调用std::function析构函数时才会删除它们。

然后,还要记住std::function尊重值语义。 这意味着如果std::function被复制,则内部的 lambda 也会被复制。 这意味着您可以自由复制、移动、从 scope 中复制一些副本,调用 function 并且不会影响其他副本。

这意味着此代码有效:

auto make_function_with_captures(double a, double b) -> std::function<double()> {
    // captures 'a' and 'b' as values
    auto lambda = [a, b] {
        return a + b;
    };

    // Here, 'lambda' is copied in the std::function
    return std::function<double()>{lambda};
    
} // 'lambda' goes out of scope here, with its captures

int main() {
    auto function = make_function_with_captures(1.2, 4.5);

    // Here, use a copy of the lambda that was created in the function        
    double a = function();
}

这不是一个额外的间接指针吗?

是的。 这将是带有虚拟调用的两个指针间接。

这是 go 的推荐方法吗?

大多数情况下,我会回答“否”这个问题,就像 98% 的情况一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM