How to store non-copyable std::function into a container?

允我心安 提交于 2021-02-07 05:45:07

问题


I want to store callbacks in a vector or another container in C++11.

One way to do so would be to store a vector of std::function. This works well for lambda or std::bind with copyable arguments.

However, if there is one non copyable (movable only) argument, it will fail due to the conversion from the lambda/std::bind internal type to the std::function...

#include <vector>

class NonCopyable {
public:
    NonCopyable() = default;
    NonCopyable(const NonCopyable &) = delete;
    NonCopyable(NonCopyable &&) = default;
};

int main() {
    std::vector<std::function<void()>> callbacks;
    callbacks.emplace_back([] {});

    NonCopyable tmp;
    callbacks.emplace_back(std::bind([](const NonCopyable &) {}, std::move(tmp)));
    // When converting the object returned by std::bind to a std::function,
    // a copy of the arguments happen so this code cannot compile.
    return 0;
}

Is there a way to move std::bind arguments into the std::function instead of copying them?


回答1:


std::ref and std::cref are meant to be used in this cases to avoid copying the object (see http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper).

Not sure that I got your question right, but this compiles for me:

#include <vector>
#include <functional>

class NonCopyable {
public:
  NonCopyable() = default;
  NonCopyable(const NonCopyable &) = delete;
  NonCopyable(NonCopyable &&) = default;
};

int main() {
    std::vector<std::function<void()>> callbacks;
    callbacks.emplace_back([] {});

    NonCopyable tmp;
    auto fun = std::bind([](const NonCopyable &) {}, std::cref(tmp));
    callbacks.emplace_back(fun);

    return 0;
}

EDIT: As mentioned in the comments, be careful about the life cycle of the referenced variable!




回答2:


You could use std::shared_ptr, which is copyable. Something like

using ptr = std::shared_ptr<NonCopyable>;
callbacks.emplace_back(std::bind([](const ptr &) {}, ptr(new NonCopyable())));

This way NonCopyable object will auto destruct on callbacks destructor.



来源:https://stackoverflow.com/questions/28208948/how-to-store-non-copyable-stdfunction-into-a-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!