我想在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而不是复制它们?
答案 0 :(得分:5)
std::ref
和std::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;
}
编辑:如评论中所述,请注意引用变量的生命周期!
答案 1 :(得分:0)
您可以使用std::shared_ptr
,这是可复制的。像
using ptr = std::shared_ptr<NonCopyable>;
callbacks.emplace_back(std::bind([](const ptr &) {}, ptr(new NonCopyable())));
这样NonCopyable对象将在回调析构函数上自动销毁。