如何将不可复制的 std::function 存储到容器中?

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

我想在 C++11 中的向量或其他容器中存储回调。

一种方法是存储 std::function 的向量。 这适用于具有可复制参数的 lambda 或 std::bind。

但是,如果有一个不可复制的(仅可移动的)参数,它将失败,因为从 lambda/std::bind 内部类型转换为 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;
}

有没有办法将 std::bind 个参数移动到 std::function 而不是复制它们?

在这种情况下,

std::refstd::cref 旨在避免复制对象(参见 http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper)。

不确定我是否答对了你的问题,但这对我来说是编译的:

#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;
}

编辑:如评论中所述,注意引用变量的生命周期!

您可以使用可复制的std::shared_ptr。像

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

这样 NonCopyable 对象将在回调析构函数时自动析构。