zoukankan      html  css  js  c++  java
  • [c++ 11x rvalue reference]

    1. 什么是rValue?lValue呢?
    rValue主要是指没有名字的变量(即临时变量/对象);lValue主要是指有名字的变量。除了lValue都是rValue(废话)。下面的例子可以比较直观的帮助理解:
    int&& n = 42;  // OK; 42 is an rvalue; n is rvalue reference.
    int k = n;     // OK; n is rValue reference and is lValue.
    int&& j = k;   // Error; k is an lvalue
    int&& m = k+1; // OK, k+1 is an rvalue
    A&  a_ref3 = A();  // Error! Note: A is a class.
    A&& a_ref4 = A();  // Ok
    Note: a rvalue reference refers to a rvalue and is a lvalue; a lvalue reference refers to a lvalue and is a lvalue.
    2. rValue reference的语法 -- &&
    3. rValue reference的意义 -- move语义。我的理解是:通过把&&声明定义为rvalue reference,从而区分开来lvalue和rvalue,从而提供了实现move语义函数的渠道。所以,rvalue reference是实现move语义的桥梁和途径。
    4. 如何使用rValue reference来获得move的benefit?
    对于你自己实现的class,你需要实现两个move语义的函数: move constructor和move operator=,如下:
    template <class T>
    class clone_ptr
    {
    private:
        T* ptr;
    public:
        // construction
        explicit clone_ptr(T* p = 0) : ptr(p) {}

        // destruction
        ~clone_ptr() {delete ptr;}

        // copy semantics
        clone_ptr(const clone_ptr& p)
            : ptr(p.ptr ? p.ptr->clone() : 0) {}

        clone_ptr& operator=(const clone_ptr& p)
        {
            if (this != &p)
            {
                delete ptr;
                ptr = p.ptr ? p.ptr->clone() : 0;
            }
            return *this;
        }

        // ************move semantics*********************
        clone_ptr(clone_ptr&& p)
            : ptr(p.ptr) {p.ptr = 0;}

        clone_ptr& operator=(clone_ptr&& p)
        {
            std::swap(ptr, p.ptr);
            return *this;
        }

        // Other operations
        T& operator*() const {return *ptr;}
        // ...
    };
    然后,你有如下两种途径来调用到这个class move语义的实现:
    1)赋值一个rvalue的clone_ptr:clone_ptr p2 = clone_ptr(new derived());
    2)通过std::move来显式的从一个lvalue获取一个rvalue reference:
    clone_ptr p1(new derived);
    // ...
    clone_ptr p2 = std::move(p1);  // p2 now owns the pointer instead of p1
    5. You can cast an lvalue to an rvalue reference.
    The STL std::move function enables you to convert an object to an rvalue reference to that object. Alternatively, you can use the static_cast keyword to cast an lvalue to an rvalue reference, as shown in the following example:

    // cast-reference.cpp
    // Compile with: /EHsc
    #include <iostream>
    using namespace std;

    // A class that contains a memory resource.
    class MemoryBlock
    {
       // TODO: Add resources for the class here.
    };

    void g(const MemoryBlock&)
    {
       cout << "In g(const MemoryBlock&)." << endl;
    }

    void g(MemoryBlock&&)
    {
       cout << "In g(MemoryBlock&&)." << endl;
    }

    int main()
    {
       MemoryBlock block;
       g(block);
       g(static_cast<MemoryBlock&&>(block));
    }

    This example produces the following output:

    In g(const MemoryBlock&).
    In g(MemoryBlock&&).

    6. 进展
    VC++2010在STL的实现中已经加入了move语义,因此其中的string,vector等class都已经支持move语义了。就算你没有显式的调用std::move来获利,当你构造比如临时的string对象时(string s = string("h") + "e" + "ll" + "o";),运行时你已经享受到了move语义所带来的效率提升。
    结论就是:你的代码中把临时变量赋值给另一个变量的地方,运行时都已经在使用move语义了!

    7. Summary: Rvalue references distinguish lvalues from rvalues. They can help you improve the performance of your applications by eliminating the need for unnecessary memory allocations and copy operations. They also enable you to write one version of a function that accepts arbitrary arguments and forwards them to another function as if the other function had been called directly.

    MSDN always writes good article: Rvalue Reference Declarator: &&

  • 相关阅读:
    JSTL EL 详解
    什么是JavaBean
    easy.jsp出现According to TLD or attribute directive in tag file, attribute value does not accept any expressions
    搭建sendmail
    系统运维工程师之路
    centos7 搭建安装zabbix3.0服务端实例(一)
    单例模式
    cassandra-压缩策略
    cassandra的坑-windows平台压缩策略
    Quick Sort
  • 原文地址:https://www.cnblogs.com/taoxu0903/p/2163980.html
Copyright © 2011-2022 走看看