Std :: vector movable lambda only, is it possible?

I would like to have a collection of lambdas, with the requirement that the lambda not be copied, only moved.
This is because lambas may need to move-capture some of their arguments that are not copyable.

Example:

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

      

After that I want to save func

to vector

, but I cannot use the type std::function

because it requires the lambdas to be copyable.

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

      

Can I do it in another way?

+3


source to share


1 answer


Sure. Just write your own function

clone that only moves. Here's a simplified version that only supports null callers, but you can see how it can be extended:

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(); }
};

      



All of the implicitly defined special member functions are already doing the right thing for us.

+3


source







All Articles