【问题标题】:std::vector of movable-only lambdas, is it possible?仅可移动 lambda 的 std::vector,有可能吗?
【发布时间】:2017-09-24 14:59:44
【问题描述】:

我想要一组 lambda,但要求不得复制 lambda,只能移动。
这是因为lambas 可能需要移动捕获它们的一些不可复制构造的参数。

例子:

NonCopyableType varName ;
auto func = [a=move(varName)](){ ... } ; //varName is move-captured

在此之后,我想将 func 存储在 vector 中,但我不能使用 std::function 类型,因为它要求 lambda 是可复制的。

vector<function<void()>> list ;
list.push_back(func) ; //won't work

是否可以通过其他方式做到这一点?

【问题讨论】:

    标签: c++ lambda c++14 move-semantics


    【解决方案1】:

    当然。只需编写您自己的 function 克隆,即只能移动。这是一个仅支持 nullary callables 的简化版本,但您可以查看如何对其进行扩展:

    class move_function
    {
        struct placeholder {
            virtual ~placeholder() = default;
            virtual void call() = 0;
        };
    
        template <class T>
        struct holder : placeholder {
            T f;
            void call() override { f(); }
        };
    
        std::unique_ptr<placeholder> f_;
    
    public:
        template <class F,
            class R = std::result_of_t<F&()>,
            std::enable_if_t<!std::convertible<std::decay_t<F>*, move_function*>::value, int> = 0>
        move_function(F&& f)
            : f_(new std::decay_t<F>{std::forward<F>(f)})
        { }
    
        void operator()() const { f_->call(); }
    };
    

    所有隐式定义的特殊成员函数已经为我们做了正确的事情。

    【讨论】:

    • 这让我想知道,为什么std::function 首先需要可复制性。 STL 容器不需要它,它们与库的其余部分配合得很好。
    • @GetFree 类型擦除的原则要求该类型提供function 提供的所有功能。 set&lt;T&gt; 的默认构造函数不需要访问T 的复制构造函数。但是当你将T转换为function&lt;ret()&gt;时,T的所有相关功能都需要立即捕获,因为function之后无法记住T
    • @Potatoswatter,简单来说,容器只需要你使用的东西。如果您不复制容器,则它不需要是可复制的。而std:function 需要所有功能,无论您是否使用它。
    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 2020-10-19
    • 2018-02-02
    • 1970-01-01
    • 2015-01-05
    • 2015-08-23
    • 2011-12-21
    相关资源
    最近更新 更多