C++ prvalue

C++17, prvalue被重新定义,我的思路都乱了。

左值(lvalue):具有id属性的值。能通过写代码的方式抓住的一个值。例如:

static int g_var=123;
int& f(){
    return g_var;
}

int main(){
    f()=456;
}

f()这个函数表达式的value catagories是lvalue。每次你写f()都能抓住相同的那个地址的值(存放在g_var)。

纯右值(prvalue):没有id属性的值,但是还能去move它。例如:

 1 #include <iostream>
 2 
 3 class S {
 4 public:
 5     
 6     S(int i) {
 7         std::cout << "S(int i) called" << std::endl;
 8         i_ = i;
 9         if (i>0)
10             m_ = new char[i];
11     }
12 
13     ~S() {
14         if (m_)
15             delete[] m_;
16     }
17 
18     S(S && other) {
19         std::cout << "S(S &&) called" << std::endl;
20         m_ = other.m_;
21         i_ = other.i_;
22         other.m_ = 0;
23     }
24 
25     S(const S & other) = delete;
26 
27 private:
28     char* m_=0;
29     int i_;
30 };
31 
32 S get() {
33     int x = 10;
34     std::cin >> x;
35     return S(x);
36 }
37 
38 int main(){
39     S s = get();
40     return 0;
41 }

39行get返回一个纯右值,通过move constructor构造S s;与前面的f()不同的是,每次调用get()都是一个不同的值。这就是说,纯右值不具有id属性。你可以抢夺纯右值,抄它的家,这就是move属性。(注:在第20行开始,就是对纯右值的抄家过程)

但是可以通过S&& ref = get() 抓住临时对象,这延长了临时对象的生命周期。再次get()仍旧是另一个临时对象,与先前ref到的是不同的值。

x值(xvalue):同时具有id属性和move属性的值。这像极了蝙蝠,可以飞也有四肢,可以加入兽群,也能加入鸟类。(“X”像不像四肢和翅膀呢?)

S tmp(123);
std::move(tmp);

std::move就是生成xvalue的神器,每次调用都会明确的指向tmp所在的地址(具有id性),但是可以传给move constructor,让别人偷窃tmp的财产。

C++17 pvalue的含义变化了,有时候pvalue是没有产生临时对象的,只是一个初始化。例如:

S get(){
    return S{123};
}

S s = get();

貌似有constructor和move constructor的调用,实际在“强制拷贝消除( Guaranteed Copy Elision ) 下,只有一个constructor的调用。依赖于move constructor副作用的人要大大的失望了(例如:希望cout出一条打印)。在编译器看来,S s = get(); 等价于 S s(  S{123} ); 等价于S{123};

根据id,move属性分类值得思路,被彻底打乱了。期望新版的the C++ Programming language对这个问题做更简明的论述。没人期望像语言律师那样扣条文的方式学习C++。

原文链接: https://www.cnblogs.com/thomas76/p/8596710.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++ prvalue

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/397560

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月11日 上午9:15
下一篇 2023年4月11日 上午9:15

相关推荐