std::thread和std::bind不使用完美转发的原因
std::thread和std::bind都是延迟调用对象的函数,参数都使用了右值引用即移动和复制语义。
std::thread:
template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );
std::bind
template< class F, class... Args > bind( F&& f, Args&&... args );
因为不确定真正的对象何时调用(线程也需要等cpu调度才能调用)。所以为了简单的保证调用时参数不被析构,所以采用复制和移动。
虽然这样保证了调用的安全性,但是不能传递参数是引用的可调用对象。必须显示的使用std::ref(xxx)或std::cref,来传递引用参数。
std::ref
template< class T > std::reference_wrapper<T> ref( T& t ) noexcept; template< class T > std::reference_wrapper<const T> cref( std::reference_wrapper<T> t ) noexcept;
ref返回一个std::reference_wrapper<T>对象,这是一个模板类,可以进行拷贝,可以隐式转换为引用T&。相当于把引用封装成一个对象。这样就可以放入std容器,或者在thread和bind的参数进行拷贝,然后又不失引用的语义。
具体使用情况可以参考:
https://blog.csdn.net/m0_51551385/article/details/123962081
TODO:有空看源码实现。