Open paulQuei opened 3 years ago
你好,关于这句话:glvalue可以自动转换成prvalue。例如:int a = b,等号右边的lvalue会自动转换成rvalue
。我没太理解。为什么等号右边的是lvalue,等号左边的是rvalue呢?一句glvalue是拥有身份的表达式,它对应了一块内存地址。glvalue有lvalue和xvalue两种形式
的说法,不应该等号左边的是lvalue吗?因为他有内存地址。
我看懂glvalue可以自动转换成prvalue。例如:int a = b,等号右边的lvalue会自动转换成rvalue
这句话了。希望您可以换个表述方法。我第一次产生误解是因为=
的缘故。我以为你说的是等号右边是lvalue
,等号左边是rvalue
。而实际上您表达的意思应该是b
本身是lvalue
,但是将其放到等号右边需要赋值给a
(a
也是lvalue
),那么b
就会隐式地发生lvalue-to-rvalue
的转变。lvalue-to-rvalue 转换实现了两件事:(1)如果某个场合需要一个 rvalue 表达式,那么 lvalue 也能用上去(比如,赋值运算符“=”的右侧,或是参与数学运算,比如 x+y )(2)它让编译器知道,应该去哪个位置读取一个变量的内存值。
const类型的左值引用是可以绑定到右值上, const int& a = 1
,那么请问内存空间是如何分配的呢?是在堆里面还是栈里面呢?const类型的左值引用
绑定右值的过程中究竟发生了什么呢?
这个报错中的lvalue就是数字表达式3的值类别。
这里应该解释成「这里“3”所在的位置需要是左值,但“3”不是」吧,而不是「表达式“3”的值类别是lvalue」
int main()
{
X h1(1000); // regular constructor
X h2(h1); // copy constructor (lvalue in input)
X h3 = createX(2000); // move constructor (rvalue in input)
h2 = h3; // assignment operator (lvalue in input)
h2 = createX(500); // move assignment operator (rvalue in input)
}
这段代码中的 X h3 = createX(2000)
应该是 X h3(createX(2000)
吗,表示移动构造函数?
最后参数应用推导过程有点小问题,不过无伤大雅,emplace_back(1) 里面推导得到的应该是: void emplace_back(int&& e) { return func(forward<int&&>(int& e)); => return static_cast<int&&>(e); }
int main() { X h1(1000); // regular constructor X h2(h1); // copy constructor (lvalue in input) X h3 = createX(2000); // move constructor (rvalue in input) h2 = h3; // assignment operator (lvalue in input) h2 = createX(500); // move assignment operator (rvalue in input) }
这段代码中的
X h3 = createX(2000)
应该是X h3(createX(2000)
吗,表示移动构造函数?
两年后过来看,发现我之前的评论是错的,当时还不清楚有多种初始化方式 😭
https://paul.pub/cpp-value-category/#id-%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99%E4%B8%8E%E6%8E%A8%E8%8D%90%E8%AF%BB%E7%89%A9
C++中的值类别, C++, lvalue,rvalue,rvalue-ref,move,perfect-forward, 表达式是C++语言的基石。每个表达式都有两个属性:类型(type)和值类别(value category)。前者是大家都熟悉的,但是后者却可能是我们不太在意的。本文的目的是介绍与值类别相关的一些知识。