我想一般地“挑选”函数调用,以便它们可以在以后执行。这些函数的返回类型将始终为 void
(目前)。像这样:
template<typename F, typename... Args>
std::function<void()>
pickle(F function, Args&&... args) {
return std::bind(F, args...);
}
问题是,如果 args
包含一个 const 引用,std::bind
会尝试复制构造该值,如果类型缺少复制构造函数。如何以使用 std::ref
进行左值引用并使用普通 std::forward
进行左值引用的方式转发参数?
例子
#include <functional>
class NonCopyable {
public:
NonCopyable() {}
NonCopyable(const NonCopyable&) = delete;
};
template<typename F, typename... Args>
std::function<void()>
pickle(F function, Args&&... args)
{
return std::bind(function, std::forward<Args>(args)...);
}
int main()
{
NonCopyable obj;
auto f = pickle(
[](const NonCopyable&) {},
obj
);
return 0;
}
上面的代码片段无法编译,提示删除了复制构造函数。 (我在这里使用 forward 是因为有人建议它,但似乎已经删除了他们的答案)。
最佳答案
重载,是的。
// also does the correct thing for `T const`
template<class T>
std::reference_wrapper<T> maybe_ref(T& v, int){ return std::ref(v); }
// just forward rvalues along
template<class T>
T&& maybe_ref(T&& v, long){ return std::forward<T>(v); }
template<typename F, typename... Args>
std::function<void()>
pickle(F function, Args&&... args) {
return std::bind(function, maybe_ref(std::forward<Args>(args), 0)...);
}
int
/long
参数和 0
参数为发现重载不明确的编译器消除了左值大小写的歧义,并且否则会造成任何伤害。
关于c++ - 在 C++11 中绑定(bind)函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15501301/