c++ - C++0x 中的完美转发是否会使 reference_wrapper 被弃用?

标签 c++ c++11

像往常一样,先写代码:

#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/

相关文章:

c++ - 我可以在 C++ 中创建强类型整数吗?

获取完整函数路径和声明的 C++ 宏

C++:SFINAE 区分填充和范围构造函数?

c++ - 搜索商业 C++ 许可库

c++ - 不访问全局对象的类

c++ - 为什么 OpenCL 嵌套循环只适用于某些元素

c++ - 如何使用强类型枚举

c++ - 使用预处理器而不是可变参数模板构建的 Boost 变体

c++ - 是否存在无法锁定(提升为 shared_ptr)的 weak_ptr 之类的东西?如果不是,为什么?

c++ - 如何使用带有 `if/else if/else`的gcovr获得100%的分支覆盖率