[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: &&

 

posted @ 2011-09-02 17:04  能巴  阅读(984)  评论(0编辑  收藏  举报