像往常一样,先写代码:
#include <functional>
using namespace std;
using namespace std::tr1;
void f(int& r) { r++; }
template<class F, class P> void g1(F f, P t) { f(t); }
template<class F, class P> void g2(F f, P&& t) { f(forward<P>(t)); }
int main()
{
int i = 0;
g1(f, ref(i)); // old way, ugly way
g2(f, i); // new way, elegant way
}
在 C++ 98 中,我们没有一个很好的方法来通过模板函数来完善前向参数。因此,C++ 专家发明了 ref 和 cref 来实现这一目标。
既然我们有了 r 值引用和完美转发,是否意味着 ref 和 cref 等应该被弃用?
最佳答案
引用包装器仍然有用。这是关于存储东西的情况。例如,使用引用包装器,您可以使 std::make_tuple 和 std::thread 创建引用某些参数而不是复制它们的对象:
class abstract_job
{
public:
virtual ~abstract_job() {}
virtual void run() = 0;
};
class thread
{
public:
template<class Fun, class... Args>
thread(Fun&& f, Args&&... args)
{
typedef typename decay<Fun>::type fun_type;
typedef decltype( make_tuple(forward<Args>(args)...) ) tuple_type;
unique_ptr<abstract_job> ptr (new my_job<fun_type,tuple_type>(
forward<Fun>(fun),
make_tuple(forward<Args>(args)...)
));
// somehow pass pointer 'ptr' to the new thread
// which is supposed to invoke ptr->run();
}
...
};
...
void foo(const int&);
int main()
{
thread t (foo, 42); // 42 is copied and foo is invoked
t.join() // with a reference to this copy
int i = 23;
thread z (foo, std::cref(i)); // foo will get a reference to i
z.join();
}
请记住
make_tuple(std::ref(i)) // yields a tuple<int&>
make_tuple( i ) // yields a tuple<int>
干杯!
关于c++ - C++0x 中的完美转发是否会使 reference_wrapper 被弃用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4327474/