C++ 11中的绑定函数参数

Ben*_*ter 7 c++ templates variadic-templates c++11

我想通常"挑选"函数调用,以便以后执行它们.这些函数的返回类型将始终是void(现在).像这样的东西:

template<typename F, typename... Args>
std::function<void()> 
pickle(F function, Args&&... args) {
    return std::bind(F, args...);
}
Run Code Online (Sandbox Code Playgroud)

问题是,如果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;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码片段无法编译,抱怨删除的拷贝构造函数.(我在这里使用过,因为有人提出了这个建议,但似乎已经删除了他们的答案,似乎).

Xeo*_*Xeo 8

超载,耶.

// 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)...);
}
Run Code Online (Sandbox Code Playgroud)

int/ long参数和0参数歧义为找到重载不明确的编译器的左值的情况下,并没有做任何伤害,否则.