看了b站bennyhuo的相关视频,记下笔记。
主要的问题就是
int i = 0;
i++;
++i;
i++ 和 ++i 返回的是左值还是右值?这还是一个面试题。
我们采用代码来验证一下,使用一个万能引用来传入表达式的返回值,然后使用 decltype 对参数的类型进行推导,最后使用 type_traits 进行左右值的判断。
#include <iostream>
#include <type_traits>
template<typename T>
void test(T&& x)
{
if (std::is_rvalue_reference<decltype(x)>::value)
{
std::cout << "rvalue" << std::endl;
}
if (std::is_lvalue_reference<decltype(x)>::value)
{
std::cout << "lvalue" << std::endl;
}
}
int main()
{
int i = 0;
test(i++); // rvalue
test(++i); // lvalue
return 0;
}
可以看到结论:表达式 i++ 是一个右值, ++i 是一个左值。
其原理也很基础,我们仿写一下 int 的前置++和后置++。
struct Integer
{
Integer(int value) : value_(value) {}
Integer(Integer& integer) : value_(integer.value_) {}
Integer& operator++()
{
++value_;
return *this;
}
Integer operator++(int)
{
Integer tmp(*this);
++value_;
return tmp;
}
int value_;
};
int main()
{
Integer x{ 1 };
test(x++); // rvalue
test(++x); // lvalue
return 0;
}
由于前置++返回的是本身的引用,而后置++返回的是一个临时的拷贝。所以表达式 x++ 返回的是一个将亡值,我们无法对其取地址,所以是一个右值,而 ++x 返回的是 x 本身,所以是一个左值。