惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
IT之家
IT之家
V
Visual Studio Blog
The Cloudflare Blog
博客园 - 司徒正美
Jina AI
Jina AI
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
S
SegmentFault 最新的问题
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿
博客园 - Franky
Last Week in AI
Last Week in AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - 能巴

[SQL Server]Index/deadlock 业务学习 [LoadRunner]负载测试工具 一般函数指针和类的成员函数指针 [P4 password]Avoiding the Perforce Prompt for Password in Windows [收藏转载]2011 APP年终总结——日均160元的收入经历 [收藏转载]我所积累的20条编程经验 [收藏转载]明星软件工程师的十种特质 Importance of Side Projects [转载]最好的HTML 5编码教程和参考手册分享 . [Mobility]移动开发概览 How Browser Works [转载]The Biggest Changes in C++11 (and Why You Should Care) Summary of Exception Exception Cost STL算法find_if和find QT信号和槽 How to set NoStepInto for VS debugging Review: Function Pointer
[c++ 11x rvalue reference]
能巴 · 2011-09-02 · via 博客园 - 能巴

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